diff --git a/cmd/serve.go b/cmd/serve.go
index 44afbfa8..e2ca14d0 100644
--- a/cmd/serve.go
+++ b/cmd/serve.go
@@ -69,14 +69,19 @@ func serve() {
didUrl := c.Param("did")
log.Debug().Msgf("DID: %s", didUrl)
- accept := strings.Split(c.Request().Header.Get(echo.HeaderAccept), ";")[0]
+ accept := c.Request().Header.Get(echo.HeaderAccept)
log.Trace().Msgf("Accept: %s", accept)
- requestedContentType := types.ContentType(accept)
- if accept == "*/*" {
+ var requestedContentType types.ContentType
+
+ if strings.Contains(accept, "*/*") || strings.Contains(accept, string(types.DIDJSONLD)) {
requestedContentType = types.DIDJSONLD
- } else if strings.Contains(accept, string(types.HTML)) {
- requestedContentType = types.HTML
+ } else if strings.Contains(accept, string(types.DIDJSON)) {
+ requestedContentType = types.DIDJSON
+ } else if strings.Contains(accept, string(types.JSONLD)) {
+ requestedContentType = types.JSONLD
+ } else {
+ requestedContentType = types.JSON
}
log.Debug().Msgf("Requested content type: %s", requestedContentType)
diff --git a/services/request_service.go b/services/request_service.go
index 3b59c072..fd1025ef 100644
--- a/services/request_service.go
+++ b/services/request_service.go
@@ -4,7 +4,6 @@ import (
// jsonpb Marshaller is deprecated, but is needed because there's only one way to proto
// marshal in combination with our proto generator version
"encoding/json"
- "fmt"
"github.com/rs/zerolog/log"
@@ -45,12 +44,6 @@ func (rs RequestService) ProcessDIDRequest(didUrl string, resolutionOptions type
log.Trace().Msgf("Resolving %s", didUrl)
result, err = rs.prepareResolutionResult(didUrl, resolutionOptions)
}
-
- if resolutionOptions.Accept == types.HTML {
- return "
Cheqd DID Resolver
", err
- }
return result, err
}
@@ -109,15 +102,18 @@ func (rs RequestService) prepareDereferencingResult(did string, dereferencingOpt
// https://w3c-ccg.github.io/did-resolution/#resolving
func (rs RequestService) Resolve(did string, resolutionOptions types.ResolutionOption) (types.DidResolution, error) {
+ if !resolutionOptions.Accept.IsSupported() {
+ return types.DidResolution{ResolutionMetadata: types.NewResolutionMetadata(did, types.JSON, types.RepresentationNotSupportedError)}, nil
+ }
didResolutionMetadata := types.NewResolutionMetadata(did, resolutionOptions.Accept, "")
if didMethod, _, _, _ := cheqdUtils.TrySplitDID(did); didMethod != rs.didMethod {
- didResolutionMetadata.ResolutionError = types.ResolutionMethodNotSupported
+ didResolutionMetadata.ResolutionError = types.MethodNotSupportedError
return types.DidResolution{ResolutionMetadata: didResolutionMetadata}, nil
}
if !cheqdUtils.IsValidDID(did, "", rs.ledgerService.GetNamespaces()) {
- didResolutionMetadata.ResolutionError = types.ResolutionInvalidDID
+ didResolutionMetadata.ResolutionError = types.InvalidDIDError
return types.DidResolution{ResolutionMetadata: didResolutionMetadata}, nil
}
@@ -133,16 +129,14 @@ func (rs RequestService) Resolve(did string, resolutionOptions types.ResolutionO
}
if !isFound {
- didResolutionMetadata.ResolutionError = types.ResolutionNotFound
+ didResolutionMetadata.ResolutionError = types.NotFoundError
return types.DidResolution{ResolutionMetadata: didResolutionMetadata}, nil
}
if didResolutionMetadata.ContentType == types.DIDJSONLD || didResolutionMetadata.ContentType == types.JSONLD {
didDoc.Context = append(didDoc.Context, types.DIDSchemaJSONLD)
- } else if didResolutionMetadata.ContentType == types.DIDJSON || didResolutionMetadata.ContentType == types.HTML {
- didDoc.Context = []string{}
} else {
- return types.DidResolution{}, fmt.Errorf("content type %s is not supported", didResolutionMetadata.ContentType)
+ didDoc.Context = []string{}
}
return types.DidResolution{Did: didDoc, Metadata: resolvedMetadata, ResolutionMetadata: didResolutionMetadata}, nil
}
@@ -152,14 +146,18 @@ func (rs RequestService) Dereference(didUrl string, dereferenceOptions types.Der
did, path, query, fragmentId, err := cheqdUtils.TrySplitDIDUrl(didUrl)
log.Info().Msgf("did: %s, path: %s, query: %s, fragmentId: %s", did, path, query, fragmentId)
+ if !dereferenceOptions.Accept.IsSupported() {
+ return types.DidDereferencing{DereferencingMetadata: types.NewDereferencingMetadata(did, types.JSON, types.RepresentationNotSupportedError)}, nil
+ }
+
if err != nil || !cheqdUtils.IsValidDIDUrl(didUrl, "", []string{}) {
- dereferencingMetadata := types.NewDereferencingMetadata(didUrl, dereferenceOptions.Accept, types.DereferencingInvalidDIDUrl)
+ dereferencingMetadata := types.NewDereferencingMetadata(didUrl, dereferenceOptions.Accept, types.InvalidDIDUrlError)
return types.DidDereferencing{DereferencingMetadata: dereferencingMetadata}, nil
}
// TODO: implement
if query != "" {
- dereferencingMetadata := types.NewDereferencingMetadata(didUrl, dereferenceOptions.Accept, types.DereferencingNotSupported)
+ dereferencingMetadata := types.NewDereferencingMetadata(didUrl, dereferenceOptions.Accept, types.RepresentationNotSupportedError)
return types.DidDereferencing{DereferencingMetadata: dereferencingMetadata}, nil
}
@@ -181,7 +179,7 @@ func (rs RequestService) dereferencePrimary(path string, did string, didUrl stri
resourceId := utils.GetResourceId(path)
// Only `resource` path is supported
if resourceId == "" {
- dereferencingMetadata := types.NewDereferencingMetadata(didUrl, dereferenceOptions.Accept, types.DereferencingNotSupported)
+ dereferencingMetadata := types.NewDereferencingMetadata(didUrl, dereferenceOptions.Accept, types.RepresentationNotSupportedError)
return types.DidDereferencing{DereferencingMetadata: dereferencingMetadata}, nil
}
@@ -190,7 +188,7 @@ func (rs RequestService) dereferencePrimary(path string, did string, didUrl stri
return types.DidDereferencing{}, err
}
if !isFound {
- dereferencingMetadata := types.NewDereferencingMetadata(didUrl, dereferenceOptions.Accept, types.DereferencingNotFound)
+ dereferencingMetadata := types.NewDereferencingMetadata(didUrl, dereferenceOptions.Accept, types.NotFoundError)
return types.DidDereferencing{DereferencingMetadata: dereferencingMetadata}, nil
}
jsonFragment, err := rs.didDocService.MarshallContentStream(&resource, dereferenceOptions.Accept)
@@ -223,7 +221,7 @@ func (rs RequestService) dereferenceSecondary(did string, fragmentId string, did
}
if protoContent == nil {
- dereferencingMetadata := types.NewDereferencingMetadata(didUrl, dereferenceOptions.Accept, types.DereferencingNotFound)
+ dereferencingMetadata := types.NewDereferencingMetadata(didUrl, dereferenceOptions.Accept, types.NotFoundError)
return types.DidDereferencing{DereferencingMetadata: dereferencingMetadata}, nil
}
diff --git a/services/request_service_test.go b/services/request_service_test.go
index c1dead4b..82a73ad9 100644
--- a/services/request_service_test.go
+++ b/services/request_service_test.go
@@ -119,15 +119,16 @@ func TestResolve(t *testing.T) {
validMetadata := validMetadata()
validResource := validResource()
subtests := []struct {
- name string
- ledgerService MockLedgerService
- resolutionType types.ContentType
- identifier string
- method string
- namespace string
- expectedDID cheqd.Did
- expectedMetadata types.ResolutionDidDocMetadata
- expectedError types.ErrorType
+ name string
+ ledgerService MockLedgerService
+ resolutionType types.ContentType
+ identifier string
+ method string
+ namespace string
+ expectedDID cheqd.Did
+ expectedMetadata types.ResolutionDidDocMetadata
+ expectedResolutionType types.ContentType
+ expectedError types.ErrorType
}{
{
name: "successful resolution",
@@ -149,7 +150,7 @@ func TestResolve(t *testing.T) {
namespace: validNamespace,
expectedDID: cheqd.Did{},
expectedMetadata: types.ResolutionDidDocMetadata{},
- expectedError: types.ResolutionNotFound,
+ expectedError: types.NotFoundError,
},
{
name: "invalid DID",
@@ -160,7 +161,7 @@ func TestResolve(t *testing.T) {
namespace: validNamespace,
expectedDID: cheqd.Did{},
expectedMetadata: types.ResolutionDidDocMetadata{},
- expectedError: types.ResolutionInvalidDID,
+ expectedError: types.InvalidDIDError,
},
{
name: "invalid method",
@@ -171,7 +172,7 @@ func TestResolve(t *testing.T) {
namespace: validNamespace,
expectedDID: cheqd.Did{},
expectedMetadata: types.ResolutionDidDocMetadata{},
- expectedError: types.ResolutionMethodNotSupported,
+ expectedError: types.MethodNotSupportedError,
},
{
name: "invalid namespace",
@@ -182,7 +183,19 @@ func TestResolve(t *testing.T) {
namespace: "invalid_namespace",
expectedDID: cheqd.Did{},
expectedMetadata: types.ResolutionDidDocMetadata{},
- expectedError: types.ResolutionInvalidDID,
+ expectedError: types.InvalidDIDError,
+ },
+ {
+ name: "representation is not supported",
+ ledgerService: NewMockLedgerService(validDIDDoc, validMetadata, validResource),
+ resolutionType: "text/html,application/xhtml+xml",
+ identifier: validIdentifier,
+ method: validMethod,
+ namespace: validNamespace,
+ expectedDID: cheqd.Did{},
+ expectedMetadata: types.ResolutionDidDocMetadata{},
+ expectedResolutionType: types.JSON,
+ expectedError: types.RepresentationNotSupportedError,
},
}
@@ -200,7 +213,10 @@ func TestResolve(t *testing.T) {
} else {
subtest.expectedDID.Context = nil
}
-
+ expectedContentType := subtest.expectedResolutionType
+ if expectedContentType == "" {
+ expectedContentType = subtest.resolutionType
+ }
resolutionResult, err := requestService.Resolve(id, types.ResolutionOption{Accept: subtest.resolutionType})
fmt.Println(subtest.name + ": resolutionResult:")
@@ -208,7 +224,7 @@ func TestResolve(t *testing.T) {
fmt.Println(subtest.expectedDID.VerificationMethod)
require.EqualValues(t, subtest.expectedDID, resolutionResult.Did)
require.EqualValues(t, subtest.expectedMetadata, resolutionResult.Metadata)
- require.EqualValues(t, subtest.resolutionType, resolutionResult.ResolutionMetadata.ContentType)
+ require.EqualValues(t, expectedContentType, resolutionResult.ResolutionMetadata.ContentType)
require.EqualValues(t, subtest.expectedError, resolutionResult.ResolutionMetadata.ResolutionError)
require.EqualValues(t, expectedDIDProperties, resolutionResult.ResolutionMetadata.DidProperties)
require.Empty(t, err)
@@ -280,7 +296,7 @@ func TestDereferencing(t *testing.T) {
didUrl: "unvalid_url",
dereferencingType: types.DIDJSONLD,
expectedMetadata: types.ResolutionDidDocMetadata{},
- expectedError: types.DereferencingInvalidDIDUrl,
+ expectedError: types.InvalidDIDUrlError,
},
{
name: "not supported path",
@@ -288,7 +304,7 @@ func TestDereferencing(t *testing.T) {
dereferencingType: types.DIDJSONLD,
didUrl: validDid + "/unknown_path",
expectedMetadata: types.ResolutionDidDocMetadata{},
- expectedError: types.DereferencingNotSupported,
+ expectedError: types.RepresentationNotSupportedError,
},
{
name: "not supported query",
@@ -296,7 +312,7 @@ func TestDereferencing(t *testing.T) {
dereferencingType: types.DIDJSONLD,
didUrl: validDid + "?unknown_query",
expectedMetadata: types.ResolutionDidDocMetadata{},
- expectedError: types.DereferencingNotSupported,
+ expectedError: types.RepresentationNotSupportedError,
},
{
name: "key not found",
@@ -304,7 +320,7 @@ func TestDereferencing(t *testing.T) {
dereferencingType: types.DIDJSONLD,
didUrl: validDid + "#notFoundKey",
expectedMetadata: types.ResolutionDidDocMetadata{},
- expectedError: types.DereferencingNotFound,
+ expectedError: types.NotFoundError,
},
{
name: "resource not found",
@@ -312,7 +328,7 @@ func TestDereferencing(t *testing.T) {
dereferencingType: types.DIDJSONLD,
didUrl: validDid + types.RESOURCE_PATH + "00000000-0000-0000-0000-000000000000",
expectedMetadata: types.ResolutionDidDocMetadata{},
- expectedError: types.DereferencingNotFound,
+ expectedError: types.NotFoundError,
},
}
@@ -320,7 +336,7 @@ func TestDereferencing(t *testing.T) {
t.Run(subtest.name, func(t *testing.T) {
requestService := NewRequestService("cheqd", subtest.ledgerService)
var expectedDIDProperties types.DidProperties
- if subtest.expectedError != types.DereferencingInvalidDIDUrl {
+ if subtest.expectedError != types.InvalidDIDUrlError {
expectedDIDProperties = types.DidProperties{
DidString: validDid,
MethodSpecificId: validIdentifier,
diff --git a/tests/pytest/helpers.py b/tests/pytest/helpers.py
index 8feda6f0..244dc455 100644
--- a/tests/pytest/helpers.py
+++ b/tests/pytest/helpers.py
@@ -23,6 +23,7 @@
DIDJSON = "application/did+json"
DIDLDJSON = "application/did+ld+json"
LDJSON = "application/ld+json"
+JSON = "application/json"
HTML = "text/html"
IMPLICIT_TIMEOUT = 40
diff --git a/tests/pytest/test_resolution.py b/tests/pytest/test_resolution.py
index 34b329c2..8973c697 100644
--- a/tests/pytest/test_resolution.py
+++ b/tests/pytest/test_resolution.py
@@ -5,13 +5,14 @@
from helpers import run, TESTNET_DID, MAINNET_DID, TESTNET_FRAGMENT, MAINNET_FRAGMENT, \
FAKE_TESTNET_DID, FAKE_MAINNET_DID, FAKE_TESTNET_FRAGMENT, FAKE_MAINNET_FRAGMENT, RESOLVER_URL, PATH, \
- LDJSON, DIDJSON, DIDLDJSON, HTML, FAKE_TESTNET_RESOURCE, TESTNET_RESOURCE, TESTNET_RESOURCE_NAME
+ LDJSON, DIDJSON, DIDLDJSON, HTML, FAKE_TESTNET_RESOURCE, TESTNET_RESOURCE, TESTNET_RESOURCE_NAME, JSON
@pytest.mark.parametrize(
"did_url, expected_output",
[
- (TESTNET_DID, fr"didResolutionMetadata(.*?)didDocument(.*?)\"id\":\"{TESTNET_DID}\"(.*?)didDocumentMetadata(.*?){TESTNET_RESOURCE_NAME}"),
+ (TESTNET_DID,
+ fr"didResolutionMetadata(.*?)didDocument(.*?)\"id\":\"{TESTNET_DID}\"(.*?)didDocumentMetadata(.*?){TESTNET_RESOURCE_NAME}"),
(MAINNET_DID, fr"didResolutionMetadata(.*?)didDocument(.*?)\"id\":\"{MAINNET_DID}\"(.*?)didDocumentMetadata"),
(FAKE_TESTNET_DID, r"\"didResolutionMetadata(.*?)\"error\":\"notFound\"(.*?)"
r"didDocument\":null,\"didDocumentMetadata\":\[\]"),
@@ -46,12 +47,13 @@ def test_resolution(did_url, expected_output):
r"(.*?)didDocument(.*?)@context(.*?)didDocumentMetadata"),
(DIDLDJSON, DIDLDJSON, True, "(.*?)didResolutionMetadata(.*?)application/did\+ld\+json"
"(.*?)didDocument(.*?)@context(.*?)didDocumentMetadata"),
- ("", DIDLDJSON, True, "(.*?)didResolutionMetadata(.*?)application/did\+ld\+json"
- "(.*?)didDocument(.*?)@context(.*?)didDocumentMetadata"),
+ ("*/*", DIDLDJSON, True, "(.*?)didResolutionMetadata(.*?)application/did\+ld\+json"
+ "(.*?)didDocument(.*?)@context(.*?)didDocumentMetadata"),
(DIDJSON, DIDJSON, False, r"(.*?)didResolutionMetadata(.*?)application/did\+json"
r"(.*?)didDocument(.*?)(?!`@context`)(.*?)didDocumentMetadata"),
- (HTML + ",application/xhtml+xml", HTML, False, fr"(.*?)didResolutionMetadata(.*?){HTML}"
- fr"(.*?)didDocument(.*?)(?!`@context`)(.*?)didDocumentMetadata"),
+ (HTML + ",application/xhtml+xml", JSON, False,
+ "(.*?)didResolutionMetadata(.*?)\"error\":\"representationNotSupported\""
+ "(.*?)\"didDocument\":null,\"didDocumentMetadata\":\[\]"),
]
)
def test_resolution_content_type(accept, expected_header, expected_body, has_context):
@@ -75,15 +77,15 @@ def test_resolution_content_type(accept, expected_header, expected_body, has_con
(DIDLDJSON, DIDLDJSON, True,
"(.*?)contentStream(.*?)@context(.*?)contentMetadata"
"(.*?)dereferencingMetadata(.*?)application/did\+ld\+json"),
- ("", DIDLDJSON, True,
+ ("*/*", DIDLDJSON, True,
"(.*?)contentStream(.*?)@context(.*?)contentMetadata"
"(.*?)dereferencingMetadata(.*?)application/did\+ld\+json"),
(DIDJSON, DIDJSON, False,
r"(.*?)contentStream(.*?)contentMetadata"
r"(.*?)dereferencingMetadata(.*?)application/did\+json"),
- (HTML + ",application/xhtml+xml", HTML, False,
- fr"(.*?)contentStream(.*?)contentMetadata"
- fr"(.*?)dereferencingMetadata(.*?){HTML}"),
+ (HTML + ",application/xhtml+xml", JSON, False,
+ "(.*?)\"contentStream\":null,\"contentMetadata\":\[\],"
+ "\"dereferencingMetadata(.*?)\"error\":\"representationNotSupported\""),
]
diff --git a/types/constants.go b/types/constants.go
index db344280..09de6502 100644
--- a/types/constants.go
+++ b/types/constants.go
@@ -3,16 +3,32 @@ package types
type ErrorType string
const (
- ResolutionInvalidDID ErrorType = "invalidDid"
- ResolutionNotFound ErrorType = "notFound"
- ResolutionMethodNotSupported ErrorType = "methodNotSupported"
+ InvalidDIDError ErrorType = "invalidDid"
+ InvalidDIDUrlError ErrorType = "invalidDidUrl"
+ NotFoundError ErrorType = "notFound"
+ RepresentationNotSupportedError ErrorType = "representationNotSupported"
+ MethodNotSupportedError ErrorType = "methodNotSupported"
+ InternalError ErrorType = "internalError"
)
-const (
- DereferencingInvalidDIDUrl ErrorType = "invalidDidUrl"
- DereferencingNotFound ErrorType = "notFound"
- DereferencingNotSupported ErrorType = "urlNotSupported"
-)
+func (e ErrorType) GetStatusCode() int {
+ switch e {
+ case InvalidDIDError:
+ return 400
+ case InvalidDIDUrlError:
+ return 400
+ case NotFoundError:
+ return 404
+ case RepresentationNotSupportedError:
+ return 406
+ case MethodNotSupportedError:
+ return 406
+ case "":
+ return 200
+ default:
+ return 500
+ }
+}
type ContentType string
@@ -20,9 +36,18 @@ const (
DIDJSON ContentType = "application/did+json"
DIDJSONLD ContentType = "application/did+ld+json"
JSONLD ContentType = "application/ld+json"
- HTML ContentType = "text/html"
+ JSON ContentType = "application/json"
)
+func (cType ContentType) IsSupported() bool {
+ supportedTypes := map[ContentType]bool{
+ DIDJSON: true,
+ DIDJSONLD: true,
+ JSONLD: true,
+ }
+ return supportedTypes[cType]
+}
+
const (
DIDSchemaJSONLD = "https://www.w3.org/ns/did/v1"
)