Skip to content
This repository has been archived by the owner on Mar 27, 2024. It is now read-only.

Commit

Permalink
refactor: Moved generic utility functions out of didexchange
Browse files Browse the repository at this point in the history
- DID doc parsing
- Destination struct construction

Signed-off-by: Filip Burlacu <[email protected]>
  • Loading branch information
Filip Burlacu committed Dec 17, 2019
1 parent 388646d commit 4da0d31
Show file tree
Hide file tree
Showing 10 changed files with 457 additions and 314 deletions.
50 changes: 50 additions & 0 deletions pkg/didcomm/common/service/destination.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package service

import (
diddoc "github.com/hyperledger/aries-framework-go/pkg/doc/did"
"github.com/hyperledger/aries-framework-go/pkg/framework/aries/api/vdri"
)

// Destination provides the recipientKeys, routingKeys, and serviceEndpoint for an outbound message.
// Can be populated from an Invitation or DIDDoc.
type Destination struct {
RecipientKeys []string
ServiceEndpoint string
RoutingKeys []string
TransportReturnRoute string
}

// GetDestination constructs a Destination struct based on the given DID and parameters
// It resolves the DID using the given VDR, and collects relevant data from the resolved DIDDoc.
func GetDestination(did, serviceType, keyType string, vdr vdri.Registry) (*Destination, error) {
didDoc, err := vdr.Resolve(did)
if err != nil {
return nil, err
}

return MakeDestination(didDoc, serviceType, keyType)
}

// MakeDestination makes a Destination object from a DID Doc, following the given parameters.
func MakeDestination(didDoc *diddoc.Doc, serviceType, keyType string) (*Destination, error) {
didCommService, err := diddoc.GetDIDCommService(didDoc, serviceType)
if err != nil {
return nil, err
}

recipientKeys, err := diddoc.GetRecipientKeys(didDoc, serviceType, keyType)
if err != nil {
return nil, err
}

return &Destination{
RecipientKeys: recipientKeys,
ServiceEndpoint: didCommService.ServiceEndpoint,
}, nil
}
146 changes: 146 additions & 0 deletions pkg/didcomm/common/service/destination_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package service

import (
"crypto/ed25519"
"crypto/rand"
"errors"
"fmt"
"testing"
"time"

"github.com/btcsuite/btcutil/base58"
"github.com/stretchr/testify/require"

"github.com/hyperledger/aries-framework-go/pkg/doc/did"
mockdiddoc "github.com/hyperledger/aries-framework-go/pkg/internal/mock/diddoc"
mockvdri "github.com/hyperledger/aries-framework-go/pkg/internal/mock/vdri"
)

func TestGetDestinationFromDID(t *testing.T) {
doc := createDIDDoc()
ed25519KeyType := "Ed25519VerificationKey2018"
didCommServiceType := "did-communication"

t.Run("successfully getting destination from public DID", func(t *testing.T) {
vdr := mockvdri.MockVDRIRegistry{ResolveValue: doc}
destination, err := GetDestination(doc.ID, didCommServiceType, ed25519KeyType, &vdr)
require.NoError(t, err)
require.NotNil(t, destination)
})

t.Run("test public key not found", func(t *testing.T) {
doc.PublicKey = nil
vdr := mockvdri.MockVDRIRegistry{ResolveValue: doc}
destination, err := GetDestination(doc.ID, didCommServiceType, ed25519KeyType, &vdr)
require.Error(t, err)
require.Contains(t, err.Error(), "key not found in DID document")
require.Nil(t, destination)
})

t.Run("test service not found", func(t *testing.T) {
doc2 := createDIDDoc()
doc2.Service = nil
vdr := mockvdri.MockVDRIRegistry{ResolveValue: doc2}
destination, err := GetDestination(doc2.ID, didCommServiceType, ed25519KeyType, &vdr)
require.Error(t, err)
require.Contains(t, err.Error(), "service not found in DID document: did-communication")
require.Nil(t, destination)
})

t.Run("test did document not found", func(t *testing.T) {
vdr := mockvdri.MockVDRIRegistry{ResolveErr: errors.New("resolver error")}
destination, err := GetDestination(doc.ID, didCommServiceType, ed25519KeyType, &vdr)
require.Error(t, err)
require.Contains(t, err.Error(), "resolver error")
require.Nil(t, destination)
})
}

func TestPrepareDestination(t *testing.T) {
ed25519KeyType := "Ed25519VerificationKey2018"
didCommServiceType := "did-communication"

t.Run("successfully prepared destination", func(t *testing.T) {
dest, err := MakeDestination(mockdiddoc.GetMockDIDDoc(), didCommServiceType, ed25519KeyType)
require.NoError(t, err)
require.NotNil(t, dest)
require.Equal(t, dest.ServiceEndpoint, "https://localhost:8090")
})

t.Run("error while getting service", func(t *testing.T) {
didDoc := mockdiddoc.GetMockDIDDoc()
didDoc.Service = nil

dest, err := MakeDestination(didDoc, didCommServiceType, ed25519KeyType)
require.Error(t, err)
require.Contains(t, err.Error(), "service not found in DID document: did-communication")
require.Nil(t, dest)
})

t.Run("error while getting recipient keys from did doc", func(t *testing.T) {
didDoc := mockdiddoc.GetMockDIDDoc()
didDoc.Service[0].RecipientKeys = []string{}

recipientKeys, err := did.GetRecipientKeys(didDoc, didCommServiceType, ed25519KeyType)
require.Error(t, err)
require.Contains(t, err.Error(), "missing recipient keys in did-communication service")
require.Nil(t, recipientKeys)
})
}

func createDIDDoc() *did.Doc {
pubKey, _ := generateKeyPair()
return createDIDDocWithKey(pubKey)
}

func generateKeyPair() (string, []byte) {
pubKey, privKey, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
panic(err)
}

return base58.Encode(pubKey[:]), privKey
}

func createDIDDocWithKey(pub string) *did.Doc {
const (
didFormat = "did:%s:%s"
didPKID = "%s#keys-%d"
didServiceID = "%s#endpoint-%d"
method = "test"
)

id := fmt.Sprintf(didFormat, method, pub[:16])
pubKeyID := fmt.Sprintf(didPKID, id, 1)
pubKey := did.PublicKey{
ID: pubKeyID,
Type: "Ed25519VerificationKey2018",
Controller: id,
Value: []byte(pub),
}
services := []did.Service{
{
ID: fmt.Sprintf(didServiceID, id, 1),
Type: "did-communication",
ServiceEndpoint: "http://localhost:58416",
Priority: 0,
RecipientKeys: []string{pubKeyID},
},
}
createdTime := time.Now()
didDoc := &did.Doc{
Context: []string{did.Context},
ID: id,
PublicKey: []did.PublicKey{pubKey},
Service: services,
Created: &createdTime,
Updated: &createdTime,
}

return didDoc
}
8 changes: 0 additions & 8 deletions pkg/didcomm/common/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,3 @@ func (m *DIDCommMsg) ThreadID() (string, error) {

return "", ErrThreadIDNotFound
}

// Destination provides the recipientKeys, routingKeys, and serviceEndpoint populated from Invitation
type Destination struct {
RecipientKeys []string
ServiceEndpoint string
RoutingKeys []string
TransportReturnRoute string
}
7 changes: 6 additions & 1 deletion pkg/didcomm/protocol/didexchange/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -636,7 +636,12 @@ func (s *Service) CreateImplicitInvitation(inviterLabel, inviterDID, inviteeLabe
return "", fmt.Errorf("resolve public did[%s]: %w", inviterDID, err)
}

dest, err := prepareDestination(didDoc)
// TODO: hardcoded key type
dest, err := service.MakeDestination(didDoc, didCommServiceType, ed25519KeyType)
if err != nil {
return "", err
}

thID := generateRandomID()
connRecord := &ConnectionRecord{
ConnectionID: generateRandomID(),
Expand Down
48 changes: 3 additions & 45 deletions pkg/didcomm/protocol/didexchange/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,14 @@ import (
"testing"
"time"

"github.com/btcsuite/btcutil/base58"
"github.com/google/uuid"
"github.com/stretchr/testify/require"

"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/model"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/decorator"
"github.com/hyperledger/aries-framework-go/pkg/doc/did"
"github.com/hyperledger/aries-framework-go/pkg/internal/mock/didcomm/protocol"
mockdiddoc "github.com/hyperledger/aries-framework-go/pkg/internal/mock/diddoc"
mockstorage "github.com/hyperledger/aries-framework-go/pkg/internal/mock/storage"
mockvdri "github.com/hyperledger/aries-framework-go/pkg/internal/mock/vdri"
"github.com/hyperledger/aries-framework-go/pkg/storage"
Expand Down Expand Up @@ -542,47 +541,6 @@ func (m *mockStore) Iterator(start, limit string) storage.StoreIterator {
return nil
}

func getMockDID() *did.Doc {
return &did.Doc{
Context: []string{"https://w3id.org/did/v1"},
ID: "did:peer:123456789abcdefghi#inbox",
Service: []did.Service{
{
ServiceEndpoint: "https://localhost:8090",
Type: "did-communication",
Priority: 0,
RecipientKeys: []string{"did:example:123456789abcdefghi#keys-2"},
},
{
ServiceEndpoint: "https://localhost:8090",
Type: "did-communication",
Priority: 1,
RecipientKeys: []string{"did:example:123456789abcdefghi#keys-1"},
},
},
PublicKey: []did.PublicKey{
{
ID: "did:example:123456789abcdefghi#keys-1",
Controller: "did:example:123456789abcdefghi",
Type: "Secp256k1VerificationKey2018",
Value: base58.Decode("H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"),
},
{
ID: "did:example:123456789abcdefghi#keys-2",
Controller: "did:example:123456789abcdefghi",
Type: "Ed25519VerificationKey2018",
Value: base58.Decode("H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"),
},
{
ID: "did:example:123456789abcdefghw#key2",
Controller: "did:example:123456789abcdefghw",
Type: "RsaVerificationKey2018",
Value: base58.Decode("H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"),
},
},
}
}

func randomString() string {
u := uuid.New()
return u.String()
Expand Down Expand Up @@ -639,7 +597,7 @@ func TestEventsSuccess(t *testing.T) {
}

func TestContinueWithPublicDID(t *testing.T) {
didDoc := getMockDID()
didDoc := mockdiddoc.GetMockDIDDoc()
svc, err := New(&protocol.MockProvider{})
require.NoError(t, err)

Expand Down Expand Up @@ -1384,7 +1342,7 @@ func TestFetchConnectionRecord(t *testing.T) {
func generateRequestMsgPayload(t *testing.T, prov provider, id, invitationID string) *service.DIDCommMsg {
store := mockstorage.NewMockStoreProvider()
ctx := context{outboundDispatcher: prov.OutboundDispatcher(),
vdriRegistry: &mockvdri.MockVDRIRegistry{CreateValue: getMockDID()},
vdriRegistry: &mockvdri.MockVDRIRegistry{CreateValue: mockdiddoc.GetMockDIDDoc()},
connectionStore: NewConnectionRecorder(nil, store.Store)}
newDidDoc, err := ctx.vdriRegistry.Create(testMethod)
require.NoError(t, err)
Expand Down
Loading

0 comments on commit 4da0d31

Please sign in to comment.