Skip to content

Commit

Permalink
Merge pull request hyperledger-archives#108 from fqutishat/101
Browse files Browse the repository at this point in the history
feat: Allow DID method to Accept supported DID prefixes
  • Loading branch information
George Aristy authored Aug 14, 2019
2 parents b74857f + 263918b commit 4380aae
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 26 deletions.
5 changes: 5 additions & 0 deletions pkg/didmethod/peer/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,8 @@ func (resl *DIDResolver) Read(did string, versionID interface{}, versionTime str

return jsonDoc, nil
}

// Accept did method
func (resl *DIDResolver) Accept(method string) bool {
return "peer" == method
}
2 changes: 1 addition & 1 deletion pkg/didmethod/peer/resolver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ func TestWithDIDResolveAPI(t *testing.T) {
err = store.Put(peerDID, peerDoc, nil)
require.NoError(t, err)

r := didresolver.New(didresolver.WithDidMethod("peer", NewDIDResolver(store)))
r := didresolver.New(didresolver.WithDidMethod(NewDIDResolver(store)))
_, err = r.Resolve(peerDID)
require.NoError(t, err)

Expand Down
12 changes: 8 additions & 4 deletions pkg/framework/didresolver/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ SPDX-License-Identifier: Apache-2.0

package didresolver

import "time"
import (
"time"
)

// ResultType input option can be used to request a certain type of result.
type ResultType int
Expand All @@ -20,6 +22,7 @@ const (
// DidMethod operations
type DidMethod interface {
Read(did string, versionID interface{}, versionTime string, noCache bool) ([]byte, error)
Accept(method string) bool
}

// resolveOpts holds the options for did resolve
Expand Down Expand Up @@ -63,15 +66,16 @@ func WithNoCache(noCache bool) ResolveOpt {

// didResolverOpts holds the options for resolver instance
type didResolverOpts struct {
didMethods map[string]DidMethod
didMethods []DidMethod
}

// Opt is a resolver instance option
type Opt func(opts *didResolverOpts)

// WithDidMethod to add did method
func WithDidMethod(id string, method DidMethod) Opt {
// DID methods are checked in the order added
func WithDidMethod(method DidMethod) Opt {
return func(opts *didResolverOpts) {
opts.didMethods[id] = method
opts.didMethods = append(opts.didMethods, method)
}
}
7 changes: 3 additions & 4 deletions pkg/framework/didresolver/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,8 @@ func TestWithNoCache(t *testing.T) {
}

func TestWithDidMethod(t *testing.T) {
opt := WithDidMethod("test", nil)
resolverOpts := &didResolverOpts{didMethods: make(map[string]DidMethod)}
opt := WithDidMethod(nil)
resolverOpts := &didResolverOpts{didMethods: make([]DidMethod, 0)}
opt(resolverOpts)
_, exist := resolverOpts.didMethods["test"]
require.True(t, exist)
require.True(t, len(resolverOpts.didMethods) == 1)
}
21 changes: 16 additions & 5 deletions pkg/framework/didresolver/didresolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ import (

// DIDResolver did resolver
type DIDResolver struct {
didMethods map[string]DidMethod
didMethods []DidMethod
}

// New return new instance of did resolver
func New(opts ...Opt) *DIDResolver {
resolverOpts := &didResolverOpts{didMethods: make(map[string]DidMethod)}
resolverOpts := &didResolverOpts{didMethods: make([]DidMethod, 0)}
// Apply options
for _, opt := range opts {
opt(resolverOpts)
Expand All @@ -44,9 +44,10 @@ func (r *DIDResolver) Resolve(did string, opts ...ResolveOpt) (*diddoc.Doc, erro

// Determine if the input DID method is supported by the DID Resolver
didMethod := didParts[1]
method, exist := r.didMethods[didMethod]
if !exist {
return nil, errors.Errorf("did method %s not supported", didMethod)
// resolve did method
method, err := r.resolveDidMethod(didMethod)
if err != nil {
return nil, err
}

// Obtain the DID Document
Expand All @@ -73,3 +74,13 @@ func (r *DIDResolver) Resolve(did string, opts ...ResolveOpt) (*diddoc.Doc, erro

return didDoc, nil
}

// resolveDidMethod resolve did method
func (r *DIDResolver) resolveDidMethod(method string) (DidMethod, error) {
for _, v := range r.didMethods {
if v.Accept(method) {
return v, nil
}
}
return nil, errors.Errorf("did method %s not supported", method)
}
57 changes: 45 additions & 12 deletions pkg/framework/didresolver/didresolver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,68 +59,101 @@ var doc = `{
}`

func TestNew(t *testing.T) {
r := New(WithDidMethod("test", nil))
_, exist := r.didMethods["test"]
require.True(t, exist)
r := New(WithDidMethod(nil))
require.True(t, len(r.didMethods) == 1)
}

func TestResolve(t *testing.T) {
t.Run("test invalid did input", func(t *testing.T) {
r := New(WithDidMethod("test", nil))
r := New(WithDidMethod(nil))
_, err := r.Resolve("did:example")
require.Error(t, err)
require.Contains(t, err.Error(), "wrong format did input")
})

t.Run("test did method not supported", func(t *testing.T) {
r := New(WithDidMethod("test", nil))
r := New(WithDidMethod(mockDidMethod{acceptFunc: func(method string) bool {
return false
}}))
_, err := r.Resolve("did:example:1234")
require.Error(t, err)
require.Contains(t, err.Error(), "did method example not supported")
})

t.Run("test did method read failed", func(t *testing.T) {
r := New(WithDidMethod("example", mockDidMethod{readErr: fmt.Errorf("read error")}))
r := New(WithDidMethod(mockDidMethod{readErr: fmt.Errorf("read error"), acceptFunc: func(method string) bool {
return true
}}))
_, err := r.Resolve("did:example:1234")
require.Error(t, err)
require.Contains(t, err.Error(), "did method read failed")
})

t.Run("test did input not found", func(t *testing.T) {
r := New(WithDidMethod("example", mockDidMethod{}))
r := New(WithDidMethod(mockDidMethod{acceptFunc: func(method string) bool {
return true
}}))
didDoc, err := r.Resolve("did:example:1234")
require.NoError(t, err)
require.Nil(t, didDoc)
})

t.Run("test did doc not valid", func(t *testing.T) {
r := New(WithDidMethod("example", mockDidMethod{readValue: []byte("wrongData")}))
r := New(WithDidMethod(mockDidMethod{readValue: []byte("wrongData"), acceptFunc: func(method string) bool {
return true
}}))
_, err := r.Resolve("did:example:1234")
require.Error(t, err)
require.Contains(t, err.Error(), "Validation of did doc failed")
})

t.Run("test result type resolution-result", func(t *testing.T) {
r := New(WithDidMethod("example", mockDidMethod{readValue: []byte(doc)}))
r := New(WithDidMethod(mockDidMethod{readValue: []byte(doc), acceptFunc: func(method string) bool {
return true
}}))
_, err := r.Resolve("did:example:1234", WithResultType(ResolutionResult))
require.Error(t, err)
require.Contains(t, err.Error(), "result type 'resolution-result' not supported")
})

t.Run("test result type did-document", func(t *testing.T) {
r := New(WithDidMethod("example", mockDidMethod{readValue: []byte(doc)}))
r := New(WithDidMethod(mockDidMethod{readValue: []byte(doc), acceptFunc: func(method string) bool {
return true
}}))
didDoc, err := r.Resolve("did:example:1234", WithResultType(DidDocumentResult))
require.NoError(t, err)
require.Equal(t, didDoc.Context[0], "https://w3id.org/did/v1")
})

t.Run("test resolve did method in order", func(t *testing.T) {
r := New(WithDidMethod(mockDidMethod{readValue: []byte("did1"), acceptFunc: func(method string) bool {
return method == "did1"
}}), WithDidMethod(mockDidMethod{readValue: []byte("did2"), acceptFunc: func(method string) bool {
return true
}}))
didMethod, err := r.resolveDidMethod("did1")
require.NoError(t, err)
v, _ := didMethod.Read("", nil, "", false)
require.Equal(t, "did1", string(v))
didMethod, err = r.resolveDidMethod("did2")
require.NoError(t, err)
v, _ = didMethod.Read("", nil, "", false)
require.Equal(t, "did2", string(v))

})

}

type mockDidMethod struct {
readValue []byte
readErr error
readValue []byte
readErr error
acceptFunc func(method string) bool
}

func (m mockDidMethod) Read(did string, versionID interface{}, versionTime string, noCache bool) ([]byte, error) {
return m.readValue, m.readErr
}

func (m mockDidMethod) Accept(method string) bool {
return m.acceptFunc(method)
}

0 comments on commit 4380aae

Please sign in to comment.