Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add status codes [DEV-1582] #22

Merged
merged 3 commits into from
Aug 8, 2022
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
8 changes: 2 additions & 6 deletions cmd/serve.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package cmd

import (
"net/http"
"strings"

"github.com/cheqd/did-resolver/services"
Expand Down Expand Up @@ -85,15 +84,12 @@ func serve() {
}
log.Debug().Msgf("Requested content type: %s", requestedContentType)

responseBody, err := requestService.ProcessDIDRequest(didUrl, types.ResolutionOption{Accept: requestedContentType})
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
}
responseBody, status := requestService.ProcessDIDRequest(didUrl, types.ResolutionOption{Accept: requestedContentType})

log.Debug().Msgf("Response body: %s", responseBody)

c.Response().Header().Set(echo.HeaderContentType, string(requestedContentType))
return c.JSONBlob(http.StatusOK, []byte(responseBody))
return c.JSONBlob(status, []byte(responseBody))
})

log.Info().Msg("Starting listener")
Expand Down
2 changes: 1 addition & 1 deletion config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ api:
listener: "0.0.0.0:1313"
resolverPath: "/1.0/identifiers/:did"

logLevel: "warn"
logLevel: "debug"
131 changes: 70 additions & 61 deletions services/request_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,136 +29,129 @@ func NewRequestService(didMethod string, ledgerService LedgerServiceI) RequestSe
}
}

func (rs RequestService) IsDidUrl(didUrl string) bool {
_, path, query, fragmentId, err := cheqdUtils.TrySplitDIDUrl(didUrl)
return err == nil && (path != "" || query != "" || fragmentId != "")
}

func (rs RequestService) ProcessDIDRequest(didUrl string, resolutionOptions types.ResolutionOption) (string, error) {
func (rs RequestService) ProcessDIDRequest(didUrl string, resolutionOptions types.ResolutionOption) (string, int) {
var result string
var err error
if rs.IsDidUrl(didUrl) {
var statusCode int
if utils.IsDidUrl(didUrl) {
log.Trace().Msgf("Dereferencing %s", didUrl)
result, err = rs.prepareDereferencingResult(didUrl, types.DereferencingOption(resolutionOptions))
result, statusCode = rs.prepareDereferencingResult(didUrl, types.DereferencingOption(resolutionOptions))
} else {
log.Trace().Msgf("Resolving %s", didUrl)
result, err = rs.prepareResolutionResult(didUrl, resolutionOptions)
result, statusCode = rs.prepareResolutionResult(didUrl, resolutionOptions)
}
return result, err
return result, statusCode
}

func (rs RequestService) prepareResolutionResult(did string, resolutionOptions types.ResolutionOption) (string, error) {
didResolution, err := rs.Resolve(did, resolutionOptions)
if err != nil {
return "", err
}

resolutionMetadata, err := json.Marshal(didResolution.ResolutionMetadata)
if err != nil {
return "", err
}

didDoc, err := rs.didDocService.MarshallDID(didResolution.Did)
if err != nil {
return "", err
}
func (rs RequestService) prepareResolutionResult(did string, resolutionOptions types.ResolutionOption) (string, int) {
didResolution := rs.Resolve(did, resolutionOptions)

metadata, err := json.Marshal(&didResolution.Metadata)
if err != nil {
return "", err
resolutionMetadata, mErr1 := json.Marshal(didResolution.ResolutionMetadata)
didDoc, mErr2 := rs.didDocService.MarshallDID(didResolution.Did)
metadata, mErr3 := json.Marshal(&didResolution.Metadata)
if mErr1 != nil || mErr2 != nil || mErr3 != nil {
Toktar marked this conversation as resolved.
Show resolved Hide resolved
log.Error().Errs("errors", []error{mErr1, mErr2, mErr3}).Msg("Marshalling error")
return createJsonResolutionInternalError(resolutionMetadata)
Toktar marked this conversation as resolved.
Show resolved Hide resolved
}

if didResolution.ResolutionMetadata.ResolutionError != "" {
didDoc, metadata = "", []byte{}
}

return createJsonResolution(didDoc, string(metadata), string(resolutionMetadata))
result, err := createJsonResolution(didDoc, string(metadata), string(resolutionMetadata))
if err != nil {
log.Error().Err(err).Msg("Marshalling error")
return createJsonResolutionInternalError([]byte{})
}
return result, didResolution.ResolutionMetadata.ResolutionError.GetStatusCode()
}

func (rs RequestService) prepareDereferencingResult(did string, dereferencingOptions types.DereferencingOption) (string, error) {
func (rs RequestService) prepareDereferencingResult(did string, dereferencingOptions types.DereferencingOption) (string, int) {
log.Info().Msgf("Dereferencing %s", did)

didDereferencing, err := rs.Dereference(did, dereferencingOptions)
if err != nil {
return "", err
}
didDereferencing := rs.Dereference(did, dereferencingOptions)

dereferencingMetadata, err := json.Marshal(didDereferencing.DereferencingMetadata)
if err != nil {
return "", err
dereferencingMetadata, mErr1 := json.Marshal(didDereferencing.DereferencingMetadata)
metadata, mErr2 := json.Marshal(didDereferencing.Metadata)
if mErr1 != nil || mErr2 != nil {
Toktar marked this conversation as resolved.
Show resolved Hide resolved
log.Error().Errs("errors", []error{mErr1, mErr2}).Msg("Marshalling error")
return createJsonDereferencingInternalError([]byte{})
}

if didDereferencing.DereferencingMetadata.ResolutionError != "" {
return createJsonDereferencing(nil, "", string(dereferencingMetadata))
didDereferencing.ContentStream = nil
metadata = []byte{}
}

metadata, err := json.Marshal(didDereferencing.Metadata)
result, err := createJsonDereferencing(didDereferencing.ContentStream, string(metadata), string(dereferencingMetadata))
if err != nil {
return "", err
log.Error().Err(err).Msg("Marshalling error")
return createJsonDereferencingInternalError(dereferencingMetadata)
}

return createJsonDereferencing(didDereferencing.ContentStream, string(metadata), string(dereferencingMetadata))
return result, didDereferencing.DereferencingMetadata.ResolutionError.GetStatusCode()
}

// https://w3c-ccg.github.io/did-resolution/#resolving
func (rs RequestService) Resolve(did string, resolutionOptions types.ResolutionOption) (types.DidResolution, error) {
func (rs RequestService) Resolve(did string, resolutionOptions types.ResolutionOption) types.DidResolution {
if !resolutionOptions.Accept.IsSupported() {
return types.DidResolution{ResolutionMetadata: types.NewResolutionMetadata(did, types.JSON, types.RepresentationNotSupportedError)}, nil
return types.DidResolution{ResolutionMetadata: types.NewResolutionMetadata(did, types.JSON, types.RepresentationNotSupportedError)}
}
didResolutionMetadata := types.NewResolutionMetadata(did, resolutionOptions.Accept, "")

if didMethod, _, _, _ := cheqdUtils.TrySplitDID(did); didMethod != rs.didMethod {
didResolutionMetadata.ResolutionError = types.MethodNotSupportedError
return types.DidResolution{ResolutionMetadata: didResolutionMetadata}, nil
return types.DidResolution{ResolutionMetadata: didResolutionMetadata}
}

if !cheqdUtils.IsValidDID(did, "", rs.ledgerService.GetNamespaces()) {
didResolutionMetadata.ResolutionError = types.InvalidDIDError
return types.DidResolution{ResolutionMetadata: didResolutionMetadata}, nil
return types.DidResolution{ResolutionMetadata: didResolutionMetadata}

}

didDoc, metadata, isFound, err := rs.ledgerService.QueryDIDDoc(did)
if err != nil {
return types.DidResolution{}, err
didResolutionMetadata.ResolutionError = types.InternalError
return types.DidResolution{ResolutionMetadata: didResolutionMetadata}
}

resolvedMetadata, err := rs.ResolveMetadata(did, metadata)
if err != nil {
return types.DidResolution{}, err
didResolutionMetadata.ResolutionError = types.InternalError
return types.DidResolution{ResolutionMetadata: didResolutionMetadata}
}

if !isFound {
didResolutionMetadata.ResolutionError = types.NotFoundError
return types.DidResolution{ResolutionMetadata: didResolutionMetadata}, nil
return types.DidResolution{ResolutionMetadata: didResolutionMetadata}
}

if didResolutionMetadata.ContentType == types.DIDJSONLD || didResolutionMetadata.ContentType == types.JSONLD {
didDoc.Context = append(didDoc.Context, types.DIDSchemaJSONLD)
} else {
didDoc.Context = []string{}
}
return types.DidResolution{Did: didDoc, Metadata: resolvedMetadata, ResolutionMetadata: didResolutionMetadata}, nil
return types.DidResolution{Did: didDoc, Metadata: resolvedMetadata, ResolutionMetadata: didResolutionMetadata}
}

// https://w3c-ccg.github.io/did-resolution/#dereferencing
func (rs RequestService) Dereference(didUrl string, dereferenceOptions types.DereferencingOption) (types.DidDereferencing, error) {
func (rs RequestService) Dereference(didUrl string, dereferenceOptions types.DereferencingOption) types.DidDereferencing {
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
return types.DidDereferencing{DereferencingMetadata: types.NewDereferencingMetadata(did, types.JSON, types.RepresentationNotSupportedError)}
}

if err != nil || !cheqdUtils.IsValidDIDUrl(didUrl, "", []string{}) {
dereferencingMetadata := types.NewDereferencingMetadata(didUrl, dereferenceOptions.Accept, types.InvalidDIDUrlError)
return types.DidDereferencing{DereferencingMetadata: dereferencingMetadata}, nil
return types.DidDereferencing{DereferencingMetadata: dereferencingMetadata}
}

// TODO: implement
if query != "" {
dereferencingMetadata := types.NewDereferencingMetadata(didUrl, dereferenceOptions.Accept, types.RepresentationNotSupportedError)
return types.DidDereferencing{DereferencingMetadata: dereferencingMetadata}, nil
return types.DidDereferencing{DereferencingMetadata: dereferencingMetadata}
}

var didDereferencing types.DidDereferencing
Expand All @@ -169,10 +162,11 @@ func (rs RequestService) Dereference(didUrl string, dereferenceOptions types.Der
}

if err != nil {
return types.DidDereferencing{}, err
dereferencingMetadata := types.NewDereferencingMetadata(didUrl, dereferenceOptions.Accept, types.InternalError)
return types.DidDereferencing{DereferencingMetadata: dereferencingMetadata}
}

return didDereferencing, nil
return didDereferencing
}

func (rs RequestService) dereferencePrimary(path string, did string, didUrl string, dereferenceOptions types.DereferencingOption) (types.DidDereferencing, error) {
Expand Down Expand Up @@ -202,16 +196,15 @@ func (rs RequestService) dereferencePrimary(path string, did string, didUrl stri
}

func (rs RequestService) dereferenceSecondary(did string, fragmentId string, didUrl string, dereferenceOptions types.DereferencingOption) (types.DidDereferencing, error) {
didResolution, err := rs.Resolve(did, types.ResolutionOption(dereferenceOptions))
if err != nil {
return types.DidDereferencing{}, err
}
metadata := didResolution.Metadata
didResolution := rs.Resolve(did, types.ResolutionOption(dereferenceOptions))

dereferencingMetadata := types.DereferencingMetadata(didResolution.ResolutionMetadata)
if dereferencingMetadata.ResolutionError != "" {
return types.DidDereferencing{DereferencingMetadata: dereferencingMetadata}, nil
}

metadata := didResolution.Metadata

var protoContent protoiface.MessageV1
if fragmentId != "" {
protoContent = rs.didDocService.GetDIDFragment(fragmentId, didResolution.Did)
Expand Down Expand Up @@ -300,3 +293,19 @@ func createJsonDereferencing(contentStream json.RawMessage, metadata string, der

return string(respJson), nil
}

func createJsonDereferencingInternalError(dereferencingMetadata []byte) (string, int) {
result, mErr := createJsonDereferencing(nil, "", string(dereferencingMetadata))
if mErr != nil {
return "", types.InternalError.GetStatusCode()
}
return result, types.InternalError.GetStatusCode()
}

func createJsonResolutionInternalError(resolutionMetadata []byte) (string, int) {
result, mErr := createJsonResolution("", "", string(resolutionMetadata))
if mErr != nil {
return "", types.InternalError.GetStatusCode()
}
return result, types.InternalError.GetStatusCode()
}
6 changes: 2 additions & 4 deletions services/request_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ func TestResolve(t *testing.T) {
if expectedContentType == "" {
expectedContentType = subtest.resolutionType
}
resolutionResult, err := requestService.Resolve(id, types.ResolutionOption{Accept: subtest.resolutionType})
resolutionResult := requestService.Resolve(id, types.ResolutionOption{Accept: subtest.resolutionType})

fmt.Println(subtest.name + ": resolutionResult:")
fmt.Println(resolutionResult.Did.VerificationMethod)
Expand All @@ -227,7 +227,6 @@ func TestResolve(t *testing.T) {
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)
})
}
}
Expand Down Expand Up @@ -346,7 +345,7 @@ func TestDereferencing(t *testing.T) {

fmt.Println(" dereferencingResult " + subtest.didUrl)

dereferencingResult, err := requestService.Dereference(subtest.didUrl, types.DereferencingOption{Accept: subtest.dereferencingType})
dereferencingResult := requestService.Dereference(subtest.didUrl, types.DereferencingOption{Accept: subtest.dereferencingType})

fmt.Println(subtest.name + ": dereferencingResult:")
fmt.Println(dereferencingResult)
Expand All @@ -355,7 +354,6 @@ func TestDereferencing(t *testing.T) {
require.EqualValues(t, subtest.dereferencingType, dereferencingResult.DereferencingMetadata.ContentType)
require.EqualValues(t, subtest.expectedError, dereferencingResult.DereferencingMetadata.ResolutionError)
require.EqualValues(t, expectedDIDProperties, dereferencingResult.DereferencingMetadata.DidProperties)
require.Empty(t, err)
})
}
}
Loading