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

Commit

Permalink
fix: interop - support did:sov being used as peer did
Browse files Browse the repository at this point in the history
New did:sov VDR wraps did:peer VDR and all httpbinding VDRs that
accept did:sov. All operations preferentially execute through
the wrapped did:peer VDR, and as fallback execute through the
httpbinding VDRs in order.

Signed-off-by: Filip Burlacu <[email protected]>
  • Loading branch information
Filip Burlacu committed Mar 23, 2021
1 parent 5ffe344 commit d6d7736
Show file tree
Hide file tree
Showing 2 changed files with 180 additions and 3 deletions.
28 changes: 25 additions & 3 deletions pkg/framework/aries/framework.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ import (
"github.com/hyperledger/aries-framework-go/pkg/store/did"
"github.com/hyperledger/aries-framework-go/pkg/store/verifiable"
"github.com/hyperledger/aries-framework-go/pkg/vdr"
"github.com/hyperledger/aries-framework-go/pkg/vdr/httpbinding"
"github.com/hyperledger/aries-framework-go/pkg/vdr/key"
"github.com/hyperledger/aries-framework-go/pkg/vdr/peer"
"github.com/hyperledger/aries-framework-go/pkg/vdr/sov"
"github.com/hyperledger/aries-framework-go/spi/storage"
)

Expand Down Expand Up @@ -377,24 +379,44 @@ func createVDR(frameworkOpts *Aries) error {
}

var opts []vdr.Option
for _, v := range frameworkOpts.vdr {
opts = append(opts, vdr.WithVDR(v))
}

p, err := peer.New(ctx.StorageProvider())
if err != nil {
return fmt.Errorf("create new vdr peer failed: %w", err)
}

// Interop: use a did:sov VDR that will prefer to store sov DID docs locally, by wrapping the did:peer VDR.

sovOpts := []sov.Option{sov.WithPeer(p)}

// find all httpbinding VDRs that sov can use
for _, vdri := range frameworkOpts.vdr {
if httpVDR, ok := vdri.(*httpbinding.VDR); ok {
if httpVDR.Accept("sov") {
sovOpts = append(sovOpts, sov.WithHttpBinding(httpVDR))
}
}
}

s, err := sov.New(sovOpts...)
if err != nil {
return fmt.Errorf("create new vdr sov failed: %w", err)
}

opts = append(opts,
vdr.WithVDR(p),
vdr.WithVDR(s),
vdr.WithDefaultServiceType(vdrapi.DIDCommServiceType),
vdr.WithDefaultServiceEndpoint(ctx.ServiceEndpoint()),
)

k := key.New()
opts = append(opts, vdr.WithVDR(k))

for _, v := range frameworkOpts.vdr {
opts = append(opts, vdr.WithVDR(v))
}

frameworkOpts.vdrRegistry = vdr.New(ctx, opts...)

return nil
Expand Down
155 changes: 155 additions & 0 deletions pkg/vdr/sov/vdr.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package sov

import (
"fmt"

"github.com/hyperledger/aries-framework-go/pkg/doc/did"
vdrapi "github.com/hyperledger/aries-framework-go/pkg/framework/aries/api/vdr"
"github.com/hyperledger/aries-framework-go/pkg/kms"
"github.com/hyperledger/aries-framework-go/pkg/vdr/httpbinding"
"github.com/hyperledger/aries-framework-go/pkg/vdr/peer"
)

// Interop: did:sov VDR provides peer capability

// VDR did:sov VDR, wrapping did:peer and httpbinding VDRs. Uses peer as primary, and httpbinding as fallback.
// Does not own the VDRs it uses.
type VDR struct {
peerVDR *peer.VDR
httpBindingVDRs []*httpbinding.VDR
}

const (
// DIDMethod is the sov did method name.
// see https://sovrin-foundation.github.io/sovrin/spec/did-method-spec-template.html#sovrin-did-method
DIDMethod = "sov"
)

// New creates new DID Resolver.
func New(opts ...Option) (*VDR, error) {
v := &VDR{}

for _, opt := range opts {
opt(v)
}

return v, nil
}

// Accept accepts DIDs with the `sov` DID method.
func (v *VDR) Accept(method string) bool {
return method == DIDMethod
}

// Create creates the given did doc in the wrapped peer.VDR.
func (v *VDR) Create(keyManager kms.KeyManager, didDoc *did.Doc,
opts ...vdrapi.DIDMethodOption) (*did.DocResolution, error) {
if v.peerVDR != nil {
doc, err := v.peerVDR.Create(keyManager, didDoc, opts...)
if err == nil {
return doc, nil
}
}

for _, vdr := range v.httpBindingVDRs {
if vdr != nil {
doc, err := vdr.Create(keyManager, didDoc, opts...)
if err == nil {
return doc, nil
}
}
}

return nil, fmt.Errorf("no wrapped VDR available for Create")
}

// Read implements didresolver.DidMethod.Read interface (https://w3c-ccg.github.io/did-resolution/#resolving-input)
func (v *VDR) Read(didID string, opts ...vdrapi.ResolveOption) (*did.DocResolution, error) {
if v.peerVDR != nil {
doc, err := v.peerVDR.Read(didID, opts...)
if err == nil {
return doc, nil
}
}

for _, vdr := range v.httpBindingVDRs {
if vdr != nil {
doc, err := vdr.Read(didID, opts...)
if err == nil {
return doc, nil
}
}
}

return nil, fmt.Errorf("no wrapped VDR available for Read")
}

// Close frees resources being maintained by vdr.
func (v *VDR) Close() error {
return nil
}

// Update did doc.
func (v *VDR) Update(didDoc *did.Doc, opts ...vdrapi.DIDMethodOption) error {
if v.peerVDR != nil {
err := v.peerVDR.Update(didDoc, opts...)
if err == nil {
return nil
}
}

for _, vdr := range v.httpBindingVDRs {
if vdr != nil {
err := vdr.Update(didDoc, opts...)
if err == nil {
return nil
}
}
}

return fmt.Errorf("not supported")
}

// Deactivate did doc.
func (v *VDR) Deactivate(didID string, opts ...vdrapi.DIDMethodOption) error {
if v.peerVDR != nil {
err := v.peerVDR.Deactivate(didID, opts...)
if err == nil {
return nil
}
}

for _, vdr := range v.httpBindingVDRs {
if vdr != nil {
err := vdr.Deactivate(didID, opts...)
if err == nil {
return nil
}
}
}

return fmt.Errorf("not supported")
}

// Option configures the sov vdr.
type Option func(opts *VDR)

// WithHttpBinding adds the given httpbinding.VDR to the list of fallback VDRs the sov VDR will use.
func WithHttpBinding(httpBindingVDR *httpbinding.VDR) Option {
return func(opts *VDR) {
opts.httpBindingVDRs = append(opts.httpBindingVDRs, httpBindingVDR)
}
}

// WithPeer sets the peer.VDR that the sov VDR will use.
func WithPeer(peerVDR *peer.VDR) Option {
return func(opts *VDR) {
opts.peerVDR = peerVDR
}
}

0 comments on commit d6d7736

Please sign in to comment.