From 08cfc35c3b64f0a955c5235c81aac9c28fef58ce Mon Sep 17 00:00:00 2001 From: Sandra Vrtikapa Date: Thu, 1 Sep 2022 17:03:06 -0400 Subject: [PATCH] chore: Add handler for did:orb in We are currently exposing two DID resolution endpoints: protected endpoint /sidetree/v1/identifiers for did:orb unprotected endpoint /1.0/identifiers for did:web and did:orb Closes #1459 Signed-off-by: Sandra Vrtikapa --- cmd/orb-server/startcmd/start.go | 9 +- pkg/discovery/endpoint/restapi/operations.go | 24 ---- .../endpoint/restapi/operations_test.go | 113 +---------------- .../didresolver/mocks/orbresolver.gen.go | 115 ++++++++++++++++++ .../didresolver/mocks/webresolver.gen.go | 113 +++++++++++++++++ pkg/document/didresolver/resolvehandler.go | 50 ++++++++ .../didresolver/resolvehandler_test.go | 64 ++++++++++ test/bdd/did_orb_steps.go | 5 - test/bdd/features/did-sidetree.feature | 26 +++- 9 files changed, 373 insertions(+), 146 deletions(-) create mode 100644 pkg/document/didresolver/mocks/orbresolver.gen.go create mode 100644 pkg/document/didresolver/mocks/webresolver.gen.go create mode 100644 pkg/document/didresolver/resolvehandler.go create mode 100644 pkg/document/didresolver/resolvehandler_test.go diff --git a/cmd/orb-server/startcmd/start.go b/cmd/orb-server/startcmd/start.go index d9d08dd60..09a083326 100644 --- a/cmd/orb-server/startcmd/start.go +++ b/cmd/orb-server/startcmd/start.go @@ -112,6 +112,7 @@ import ( localdiscovery "github.com/trustbloc/orb/pkg/discovery/did/local" discoveryclient "github.com/trustbloc/orb/pkg/discovery/endpoint/client" discoveryrest "github.com/trustbloc/orb/pkg/discovery/endpoint/restapi" + "github.com/trustbloc/orb/pkg/document/didresolver" "github.com/trustbloc/orb/pkg/document/remoteresolver" "github.com/trustbloc/orb/pkg/document/resolvehandler" "github.com/trustbloc/orb/pkg/document/updatehandler" @@ -1174,7 +1175,7 @@ func startOrbServices(parameters *orbParameters) error { didDiscovery := localdiscovery.New(parameters.didNamespace, observer.Publisher(), endpointClient) - orbDocResolveHandler := resolvehandler.NewResolveHandler( + orbResolveHandler := resolvehandler.NewResolveHandler( parameters.didNamespace, didDocHandler, didDiscovery, @@ -1199,7 +1200,7 @@ func startOrbServices(parameters *orbParameters) error { } webResolveHandler := webresolver.NewResolveHandler(u, parameters.didNamespace, - unpublishedDIDLabel, orbDocResolveHandler, metrics.Get()) + unpublishedDIDLabel, orbResolveHandler, metrics.Get()) // create discovery rest api endpointDiscoveryOp, err := discoveryrest.New( @@ -1245,9 +1246,11 @@ func startOrbServices(parameters *orbParameters) error { handlers := make([]restcommon.HTTPHandler, 0) + didResolveHandler := didresolver.NewResolveHandler(orbResolveHandler, webResolveHandler) + handlers = append(handlers, auth.NewHandlerWrapper(diddochandler.NewUpdateHandler(baseUpdatePath, orbDocUpdateHandler, pc, metrics.Get()), authTokenManager), - signature.NewHandlerWrapper(diddochandler.NewResolveHandler(baseResolvePath, orbDocResolveHandler, metrics.Get()), + signature.NewHandlerWrapper(diddochandler.NewResolveHandler(baseResolvePath, didResolveHandler, metrics.Get()), &aphandler.Config{ ObjectIRI: apServiceIRI, VerifyActorInSignature: parameters.httpSignaturesEnabled, diff --git a/pkg/discovery/endpoint/restapi/operations.go b/pkg/discovery/endpoint/restapi/operations.go index c626decb8..8e993d23c 100644 --- a/pkg/discovery/endpoint/restapi/operations.go +++ b/pkg/discovery/endpoint/restapi/operations.go @@ -46,8 +46,6 @@ const ( orbWebDIDFileEndpoint = "/scid/{id}/did.json" nodeInfoEndpoint = "/.well-known/nodeinfo" - orbWebDIDResolverEndpoint = "/1.0/identifiers/did:web:%s:scid:{id}" - selfRelation = "self" alternateRelation = "alternate" viaRelation = "via" @@ -194,7 +192,6 @@ func (o *Operation) GetRESTHandlers() []common.HTTPHandler { newHTTPHandler(webDIDEndpoint, o.webDIDHandler), newHTTPHandler(nodeInfoEndpoint, o.nodeInfoHandler), newHTTPHandler(orbWebDIDFileEndpoint, o.orbWebDIDFileHandler), - newHTTPHandler(fmt.Sprintf(orbWebDIDResolverEndpoint, o.domainWithPort), o.orbWebDIDResolverHandler), } // Only expose a service DID endpoint if the service ID is configured to be a DID. @@ -241,27 +238,6 @@ func (o *Operation) orbWebDIDFileHandler(rw http.ResponseWriter, r *http.Request writeResponse(rw, result.Document) } -func (o *Operation) orbWebDIDResolverHandler(rw http.ResponseWriter, r *http.Request) { - id := mux.Vars(r)["id"] - - result, err := o.webResolver.ResolveDocument(id) - if err != nil { - if errors.Is(err, orberrors.ErrContentNotFound) { - logger.Debugf("web resource[%s] not found", id) - - writeErrorResponse(rw, http.StatusNotFound, "resource not found") - } else { - logger.Warnf("error returning web resource [%s]: %s", id, err) - - writeErrorResponse(rw, http.StatusInternalServerError, "error retrieving resource") - } - - return - } - - writeResponse(rw, result) -} - // webDIDHandler swagger:route Get /.well-known/did.json discovery wellKnownDIDReq // // webDIDHandler. diff --git a/pkg/discovery/endpoint/restapi/operations_test.go b/pkg/discovery/endpoint/restapi/operations_test.go index 6620688e7..60594cdc6 100644 --- a/pkg/discovery/endpoint/restapi/operations_test.go +++ b/pkg/discovery/endpoint/restapi/operations_test.go @@ -42,8 +42,7 @@ const ( hostMetaEndpoint = "/.well-known/host-meta" nodeInfoEndpoint = "/.well-known/nodeinfo" - orbWebDIDFileEndpoint = "/scid/{id}/did.json" - orbWebDIDResolverEndpoint = "/1.0/identifiers/did:web:base:scid:{id}" + orbWebDIDFileEndpoint = "/scid/{id}/did.json" suffix = "suffix" ) @@ -133,7 +132,7 @@ func TestGetRESTHandlers(t *testing.T) { &restapi.Providers{}, ) require.NoError(t, err) - require.Equal(t, 8, len(c.GetRESTHandlers())) + require.Equal(t, 7, len(c.GetRESTHandlers())) }) t.Run("HTTP service ID Success", func(t *testing.T) { @@ -145,8 +144,8 @@ func TestGetRESTHandlers(t *testing.T) { c, err := restapi.New(cfg, &restapi.Providers{}) require.NoError(t, err) - require.Equal(t, 9, len(c.GetRESTHandlers()), - "Expecting 9 handlers, including the service did handler") + require.Equal(t, 8, len(c.GetRESTHandlers()), + "Expecting 8 handlers, including the service did handler") }) } @@ -761,110 +760,6 @@ func TestWellKnownServiceDID(t *testing.T) { require.Equal(t, "https://example.com", u) } -func TestOrbWebDIDResolver(t *testing.T) { - t.Run("success", func(t *testing.T) { - didDoc := make(document.Document) - - wr := &endpointmocks.WebResolver{} - wr.ResolveDocumentReturns(&document.ResolutionResult{Document: didDoc}, nil) - - c, err := restapi.New(&restapi.Config{ - OperationPath: "/op", - ResolutionPath: "/resolve", - WebCASPath: "/cas", - ServiceEndpointURL: testutil.MustParseURL("http://base/services/orb"), - }, - &restapi.Providers{WebResolver: wr}) - require.NoError(t, err) - - handler := getHandler(t, c, orbWebDIDResolverEndpoint) - - urlVars := make(map[string]string) - urlVars["id"] = suffix - - rr := serveHTTP(t, handler.Handler(), http.MethodGet, orbWebDIDResolverEndpoint, - nil, urlVars, false) - - require.Equal(t, http.StatusOK, rr.Code) - }) - - t.Run("success - port provided", func(t *testing.T) { - didDoc := make(document.Document) - - wr := &endpointmocks.WebResolver{} - wr.ResolveDocumentReturns(&document.ResolutionResult{Document: didDoc}, nil) - - c, err := restapi.New(&restapi.Config{ - OperationPath: "/op", - ResolutionPath: "/resolve", - WebCASPath: "/cas", - ServiceEndpointURL: testutil.MustParseURL("http://base:8080/services/orb"), - }, - &restapi.Providers{WebResolver: wr}) - require.NoError(t, err) - - handler := getHandler(t, c, "/1.0/identifiers/did:web:base%3A8080:scid:{id}") - - urlVars := make(map[string]string) - urlVars["id"] = suffix - - rr := serveHTTP(t, handler.Handler(), http.MethodGet, orbWebDIDResolverEndpoint, - nil, urlVars, false) - - require.Equal(t, http.StatusOK, rr.Code) - }) - - t.Run("error - resource not found", func(t *testing.T) { - wr := &endpointmocks.WebResolver{} - wr.ResolveDocumentReturns(nil, orberrors.ErrContentNotFound) - - c, err := restapi.New(&restapi.Config{ - OperationPath: "/op", - ResolutionPath: "/resolve", - WebCASPath: "/cas", - ServiceEndpointURL: testutil.MustParseURL("http://base/services/orb"), - }, - &restapi.Providers{WebResolver: wr}) - require.NoError(t, err) - - handler := getHandler(t, c, orbWebDIDResolverEndpoint) - - urlVars := make(map[string]string) - urlVars["id"] = suffix - - rr := serveHTTP(t, handler.Handler(), http.MethodGet, orbWebDIDResolverEndpoint, - nil, urlVars, false) - - require.Equal(t, http.StatusNotFound, rr.Code) - require.Contains(t, rr.Body.String(), "resource not found") - }) - - t.Run("error - internal server error", func(t *testing.T) { - wr := &endpointmocks.WebResolver{} - wr.ResolveDocumentReturns(nil, fmt.Errorf("internal error")) - - c, err := restapi.New(&restapi.Config{ - OperationPath: "/op", - ResolutionPath: "/resolve", - WebCASPath: "/cas", - ServiceEndpointURL: testutil.MustParseURL("http://base/services/orb"), - }, - &restapi.Providers{WebResolver: wr}) - require.NoError(t, err) - - handler := getHandler(t, c, orbWebDIDResolverEndpoint) - - urlVars := make(map[string]string) - urlVars["id"] = suffix - - rr := serveHTTP(t, handler.Handler(), http.MethodGet, orbWebDIDResolverEndpoint, - nil, urlVars, false) - - require.Equal(t, http.StatusInternalServerError, rr.Code) - require.Contains(t, rr.Body.String(), "error retrieving resource") - }) -} - func TestOrbWebDIDFile(t *testing.T) { t.Run("success", func(t *testing.T) { didDoc := make(document.Document) diff --git a/pkg/document/didresolver/mocks/orbresolver.gen.go b/pkg/document/didresolver/mocks/orbresolver.gen.go new file mode 100644 index 000000000..6b20ff3fe --- /dev/null +++ b/pkg/document/didresolver/mocks/orbresolver.gen.go @@ -0,0 +1,115 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package mocks + +import ( + "sync" + + "github.com/trustbloc/sidetree-core-go/pkg/document" +) + +type OrbResolver struct { + ResolveDocumentStub func(string, ...document.ResolutionOption) (*document.ResolutionResult, error) + resolveDocumentMutex sync.RWMutex + resolveDocumentArgsForCall []struct { + arg1 string + arg2 []document.ResolutionOption + } + resolveDocumentReturns struct { + result1 *document.ResolutionResult + result2 error + } + resolveDocumentReturnsOnCall map[int]struct { + result1 *document.ResolutionResult + result2 error + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *OrbResolver) ResolveDocument(arg1 string, arg2 ...document.ResolutionOption) (*document.ResolutionResult, error) { + fake.resolveDocumentMutex.Lock() + ret, specificReturn := fake.resolveDocumentReturnsOnCall[len(fake.resolveDocumentArgsForCall)] + fake.resolveDocumentArgsForCall = append(fake.resolveDocumentArgsForCall, struct { + arg1 string + arg2 []document.ResolutionOption + }{arg1, arg2}) + fake.recordInvocation("ResolveDocument", []interface{}{arg1, arg2}) + fake.resolveDocumentMutex.Unlock() + if fake.ResolveDocumentStub != nil { + return fake.ResolveDocumentStub(arg1, arg2...) + } + if specificReturn { + return ret.result1, ret.result2 + } + fakeReturns := fake.resolveDocumentReturns + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *OrbResolver) ResolveDocumentCallCount() int { + fake.resolveDocumentMutex.RLock() + defer fake.resolveDocumentMutex.RUnlock() + return len(fake.resolveDocumentArgsForCall) +} + +func (fake *OrbResolver) ResolveDocumentCalls(stub func(string, ...document.ResolutionOption) (*document.ResolutionResult, error)) { + fake.resolveDocumentMutex.Lock() + defer fake.resolveDocumentMutex.Unlock() + fake.ResolveDocumentStub = stub +} + +func (fake *OrbResolver) ResolveDocumentArgsForCall(i int) (string, []document.ResolutionOption) { + fake.resolveDocumentMutex.RLock() + defer fake.resolveDocumentMutex.RUnlock() + argsForCall := fake.resolveDocumentArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2 +} + +func (fake *OrbResolver) ResolveDocumentReturns(result1 *document.ResolutionResult, result2 error) { + fake.resolveDocumentMutex.Lock() + defer fake.resolveDocumentMutex.Unlock() + fake.ResolveDocumentStub = nil + fake.resolveDocumentReturns = struct { + result1 *document.ResolutionResult + result2 error + }{result1, result2} +} + +func (fake *OrbResolver) ResolveDocumentReturnsOnCall(i int, result1 *document.ResolutionResult, result2 error) { + fake.resolveDocumentMutex.Lock() + defer fake.resolveDocumentMutex.Unlock() + fake.ResolveDocumentStub = nil + if fake.resolveDocumentReturnsOnCall == nil { + fake.resolveDocumentReturnsOnCall = make(map[int]struct { + result1 *document.ResolutionResult + result2 error + }) + } + fake.resolveDocumentReturnsOnCall[i] = struct { + result1 *document.ResolutionResult + result2 error + }{result1, result2} +} + +func (fake *OrbResolver) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.resolveDocumentMutex.RLock() + defer fake.resolveDocumentMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *OrbResolver) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} diff --git a/pkg/document/didresolver/mocks/webresolver.gen.go b/pkg/document/didresolver/mocks/webresolver.gen.go new file mode 100644 index 000000000..c05ed7349 --- /dev/null +++ b/pkg/document/didresolver/mocks/webresolver.gen.go @@ -0,0 +1,113 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package mocks + +import ( + "sync" + + "github.com/trustbloc/sidetree-core-go/pkg/document" +) + +type WebResolver struct { + ResolveDocumentStub func(string) (*document.ResolutionResult, error) + resolveDocumentMutex sync.RWMutex + resolveDocumentArgsForCall []struct { + arg1 string + } + resolveDocumentReturns struct { + result1 *document.ResolutionResult + result2 error + } + resolveDocumentReturnsOnCall map[int]struct { + result1 *document.ResolutionResult + result2 error + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *WebResolver) ResolveDocument(arg1 string) (*document.ResolutionResult, error) { + fake.resolveDocumentMutex.Lock() + ret, specificReturn := fake.resolveDocumentReturnsOnCall[len(fake.resolveDocumentArgsForCall)] + fake.resolveDocumentArgsForCall = append(fake.resolveDocumentArgsForCall, struct { + arg1 string + }{arg1}) + fake.recordInvocation("ResolveDocument", []interface{}{arg1}) + fake.resolveDocumentMutex.Unlock() + if fake.ResolveDocumentStub != nil { + return fake.ResolveDocumentStub(arg1) + } + if specificReturn { + return ret.result1, ret.result2 + } + fakeReturns := fake.resolveDocumentReturns + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *WebResolver) ResolveDocumentCallCount() int { + fake.resolveDocumentMutex.RLock() + defer fake.resolveDocumentMutex.RUnlock() + return len(fake.resolveDocumentArgsForCall) +} + +func (fake *WebResolver) ResolveDocumentCalls(stub func(string) (*document.ResolutionResult, error)) { + fake.resolveDocumentMutex.Lock() + defer fake.resolveDocumentMutex.Unlock() + fake.ResolveDocumentStub = stub +} + +func (fake *WebResolver) ResolveDocumentArgsForCall(i int) string { + fake.resolveDocumentMutex.RLock() + defer fake.resolveDocumentMutex.RUnlock() + argsForCall := fake.resolveDocumentArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *WebResolver) ResolveDocumentReturns(result1 *document.ResolutionResult, result2 error) { + fake.resolveDocumentMutex.Lock() + defer fake.resolveDocumentMutex.Unlock() + fake.ResolveDocumentStub = nil + fake.resolveDocumentReturns = struct { + result1 *document.ResolutionResult + result2 error + }{result1, result2} +} + +func (fake *WebResolver) ResolveDocumentReturnsOnCall(i int, result1 *document.ResolutionResult, result2 error) { + fake.resolveDocumentMutex.Lock() + defer fake.resolveDocumentMutex.Unlock() + fake.ResolveDocumentStub = nil + if fake.resolveDocumentReturnsOnCall == nil { + fake.resolveDocumentReturnsOnCall = make(map[int]struct { + result1 *document.ResolutionResult + result2 error + }) + } + fake.resolveDocumentReturnsOnCall[i] = struct { + result1 *document.ResolutionResult + result2 error + }{result1, result2} +} + +func (fake *WebResolver) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.resolveDocumentMutex.RLock() + defer fake.resolveDocumentMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *WebResolver) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} diff --git a/pkg/document/didresolver/resolvehandler.go b/pkg/document/didresolver/resolvehandler.go new file mode 100644 index 000000000..fdfcf8cdd --- /dev/null +++ b/pkg/document/didresolver/resolvehandler.go @@ -0,0 +1,50 @@ +/* +Copyright SecureKey Technologies Inc. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package didresolver + +import ( + "fmt" + "strings" + + "github.com/trustbloc/sidetree-core-go/pkg/document" +) + +type webResolver interface { + ResolveDocument(id string) (*document.ResolutionResult, error) +} + +type orbResolver interface { + ResolveDocument(id string, opts ...document.ResolutionOption) (*document.ResolutionResult, error) +} + +// ResolveHandler resolves did:orb and did:web (produced from did:orb) documents. +type ResolveHandler struct { + webResolver + orbResolver +} + +// NewResolveHandler returns a new did document resolve handler. Supported methods are did:orb and did:web. +func NewResolveHandler(orbResolver orbResolver, webResolver webResolver) *ResolveHandler { + rh := &ResolveHandler{ + orbResolver: orbResolver, + webResolver: webResolver, + } + + return rh +} + +// ResolveDocument resolves a did document. +func (r *ResolveHandler) ResolveDocument(id string, opts ...document.ResolutionOption) (*document.ResolutionResult, error) { //nolint:lll + switch { + case strings.HasPrefix(id, "did:orb"): + return r.orbResolver.ResolveDocument(id, opts...) + case strings.HasPrefix(id, "did:web"): + return r.webResolver.ResolveDocument(id) + default: + return nil, fmt.Errorf("did method not supported for id[%s]", id) + } +} diff --git a/pkg/document/didresolver/resolvehandler_test.go b/pkg/document/didresolver/resolvehandler_test.go new file mode 100644 index 000000000..b82b3498e --- /dev/null +++ b/pkg/document/didresolver/resolvehandler_test.go @@ -0,0 +1,64 @@ +/* +Copyright SecureKey Technologies Inc. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package didresolver + +//go:generate counterfeiter -o ./mocks/webresolver.gen.go --fake-name WebResolver . webResolver +//go:generate counterfeiter -o ./mocks/orbresolver.gen.go --fake-name OrbResolver . orbResolver + +import ( + "testing" + + "github.com/stretchr/testify/require" + "github.com/trustbloc/sidetree-core-go/pkg/document" + + "github.com/trustbloc/orb/pkg/document/didresolver/mocks" +) + +func TestResolveHandler_Resolve(t *testing.T) { + t.Run("success - orb document", func(t *testing.T) { + orbResolver := &mocks.OrbResolver{} + orbResolver.ResolveDocumentReturns(&document.ResolutionResult{}, nil) + + webResolver := &mocks.WebResolver{} + webResolver.ResolveDocumentReturns(&document.ResolutionResult{}, nil) + + handler := NewResolveHandler(orbResolver, webResolver) + + response, err := handler.ResolveDocument("did:orb:suffix") + require.NoError(t, err) + require.NotNil(t, response) + }) + + t.Run("success - web document", func(t *testing.T) { + orbResolver := &mocks.OrbResolver{} + orbResolver.ResolveDocumentReturns(&document.ResolutionResult{}, nil) + + webResolver := &mocks.WebResolver{} + webResolver.ResolveDocumentReturns(&document.ResolutionResult{}, nil) + + handler := NewResolveHandler(orbResolver, webResolver) + + response, err := handler.ResolveDocument("did:web:suffix") + require.NoError(t, err) + require.NotNil(t, response) + }) + + t.Run("error - did method not supported", func(t *testing.T) { + orbResolver := &mocks.OrbResolver{} + orbResolver.ResolveDocumentReturns(&document.ResolutionResult{}, nil) + + webResolver := &mocks.WebResolver{} + webResolver.ResolveDocumentReturns(&document.ResolutionResult{}, nil) + + handler := NewResolveHandler(orbResolver, webResolver) + + response, err := handler.ResolveDocument("did:other:suffix") + require.Error(t, err) + require.Nil(t, response) + require.Contains(t, err.Error(), "did method not supported") + }) +} diff --git a/test/bdd/did_orb_steps.go b/test/bdd/did_orb_steps.go index adbf853a2..61535ed1f 100644 --- a/test/bdd/did_orb_steps.go +++ b/test/bdd/did_orb_steps.go @@ -366,11 +366,6 @@ func (d *DIDOrbSteps) clientVerifiesWebDocumentFromOrbDocument(didWebVar, didOrb } return diddoctransformer.VerifyWebDocumentFromOrbDocument(&didWebResolutionResult, &didOrbResolutionResult) - if err != nil { - return err - } - - return nil } func (d *DIDOrbSteps) clientFailsToVerifyResolvedDocument() error { diff --git a/test/bdd/features/did-sidetree.feature b/test/bdd/features/did-sidetree.feature index fa9809ad2..75e03c00e 100644 --- a/test/bdd/features/did-sidetree.feature +++ b/test/bdd/features/did-sidetree.feature @@ -480,10 +480,12 @@ Feature: # test did:web document not found When an HTTP GET is sent to "https://orb.domain3.com/scid/non-existent/did.json" and the returned status code is 404 - # test did:web document not found for identifiers endpoint - When an HTTP GET is sent to "https://orb.domain3.com/1.0/identifiers/did:web:other.com:scid:suffix" and the returned status code is 404 - When an HTTP GET is sent to "https://orb.domain3.com/1.0/identifiers/did:web:orb.domain3.com:scid:suffix" and the returned status code is 404 + When an HTTP GET is sent to "https://orb.domain3.com/sidetree/v1/identifiers/did:web:other.com:scid:suffix" and the returned status code is 404 + When an HTTP GET is sent to "https://orb.domain3.com/sidetree/v1/identifiers/did:web:orb.domain3.com:scid:suffix" and the returned status code is 404 + + # test invalid did method + When an HTTP GET is sent to "https://orb.domain3.com/sidetree/v1/identifiers/did:other:suffix" and the returned status code is 500 When client sends request to "https://orb.domain3.com/sidetree/v1/operations" to create DID document and the suffix is saved to variable "didSuffix" @@ -494,18 +496,32 @@ Feature: # test unpublished existing DID When an HTTP GET is sent to "https://orb.domain3.com/scid/${didSuffix}/did.json" - When an HTTP GET is sent to "https://orb.domain3.com/1.0/identifiers/did:web:orb.domain3.com:scid:${didSuffix}" + When an HTTP GET is sent to "https://orb.domain3.com/sidetree/v1/identifiers/did:web:orb.domain3.com:scid:${didSuffix}" Then the response is saved to variable "webResponse" Then client verifies that web document from variable "webResponse" is produced from orb document from variable "orbResponse" When client sends request to "https://orb.domain3.com/sidetree/v1/identifiers" to resolve DID document with interim did Then check success response contains "canonicalId" + Then the response is saved to variable "orbResponse" + And the JSON path "didDocumentMetadata.equivalentId.#" of the response has 3 items + And the JSON path "didDocumentMetadata.equivalentId.0" of the response is saved to variable "eqid_0" + And the JSON path "didDocumentMetadata.equivalentId.1" of the response is saved to variable "eqid_1" # test published did without corresponding did:web in also known as When an HTTP GET is sent to "https://orb.domain3.com/scid/${didSuffix}/did.json" - When an HTTP GET is sent to "https://orb.domain3.com/1.0/identifiers/did:web:orb.domain3.com:scid:${didSuffix}" + When an HTTP GET is sent to "https://orb.domain3.com/sidetree/v1/identifiers/did:web:orb.domain3.com:scid:${didSuffix}" + Then the response is saved to variable "webResponse" + + Then client verifies that web document from variable "webResponse" is produced from orb document from variable "orbResponse" + + # test unpublished ID + When an HTTP GET is sent to "https://orb.domain3.com/sidetree/v1/identifiers/did:orb:uAAA:${didSuffix}" + + # test equivalent IDs (canonical, HL) + When an HTTP GET is sent to "https://orb.domain3.com/sidetree/v1/identifiers/${eqid_0}" + When an HTTP GET is sent to "https://orb.domain3.com/sidetree/v1/identifiers/${eqid_1}" When client sends request to "https://orb.domain3.com/sidetree/v1/operations" to add also known as URI "did:web:orb.domain3.com:scid:${didSuffix}" to DID document Then check for request success