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

feat: Allow DID method to Accept supported DID prefixes #108

Merged
merged 1 commit into from
Aug 14, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should update the package docs to indicate that regular expressions are supported and DID methods are checked in the order added.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I add comment

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

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)
}