Skip to content

Commit

Permalink
Add ordered maps, update tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Toktar committed Jul 7, 2022
1 parent 68feb03 commit da2ac42
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 87 deletions.
73 changes: 51 additions & 22 deletions services/diddoc_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
resource "github.com/cheqd/cheqd-node/x/resource/types"
"github.com/cheqd/did-resolver/types"
"github.com/golang/protobuf/jsonpb" //nolint
"github.com/iancoleman/orderedmap"
"google.golang.org/protobuf/runtime/protoiface"
)

Expand Down Expand Up @@ -42,12 +43,15 @@ func (ds DIDDocService) MarshallDID(didDoc cheqd.Did) (string, error) {
if err != nil {
return "", err
}
mapDID[verificationMethod] = formatedVerificationMethod
mapDID.Set(verificationMethod, json.RawMessage(formatedVerificationMethod))

// Context changes
if val, ok := mapDID[didContext]; ok {
mapDID["@"+didContext] = val
delete(mapDID, didContext)
if val, ok := mapDID.Get(didContext); ok {
mapDID.Set("@"+didContext, val)
mapDID.Delete(didContext)
mapDID.Sort(func(a *orderedmap.Pair, b *orderedmap.Pair) bool {
return a.Key() == "@"+didContext
})
}

result, err := json.Marshal(mapDID)
Expand All @@ -58,7 +62,7 @@ func (ds DIDDocService) MarshallDID(didDoc cheqd.Did) (string, error) {
}

func (ds DIDDocService) MarshallContentStream(contentStream protoiface.MessageV1, contentType types.ContentType) (string, error) {
var mapContent map[string]interface{}
var mapContent orderedmap.OrderedMap
var err error
var context types.ContentType
if contentType == types.DIDJSONLD || contentType == types.JSONLD {
Expand All @@ -68,14 +72,30 @@ func (ds DIDDocService) MarshallContentStream(contentStream protoiface.MessageV1
// VerKey changes, marshal
if verificationMethod, ok := contentStream.(*cheqd.VerificationMethod); ok {
mapContent, err = ds.prepareJWKPubkey(verificationMethod)
// Resource changes, marshal
} else if didDoc, ok := contentStream.(*cheqd.Did); ok {
didDoc.Context = []string{string(context)}
jsonDid, err := ds.MarshallDID(*didDoc)
if err != nil {
return "", err
}
return string(jsonDid), nil
// Resource changes, marshal
} else if resource, ok := contentStream.(*resource.Resource); ok {
dResource := types.DereferencedResource{
Context: []string{string(context)},
ResourceHeader: *resource.Header,
Data: resource.Data,
Context: []string{string(context)},
CollectionId: resource.Header.CollectionId,
Id: resource.Header.Id,
Name: resource.Header.Name,
ResourceType: resource.Header.ResourceType,
MediaType: resource.Header.MediaType,
Created: resource.Header.Created,
Checksum: resource.Header.Checksum,
PreviousVersionId: resource.Header.PreviousVersionId,
NextVersionId: resource.Header.NextVersionId,
Data: resource.Data,
}
jsonResource, err := json.Marshal(dResource)

if err != nil {
return "", err
}
Expand All @@ -90,7 +110,10 @@ func (ds DIDDocService) MarshallContentStream(contentStream protoiface.MessageV1

// Context changes
if context != "" {
mapContent["@"+didContext] = context
mapContent.Set("@"+didContext, context)
mapContent.Sort(func(a *orderedmap.Pair, b *orderedmap.Pair) bool {
return a.Key() == "@"+didContext
})
}

result, err := json.Marshal(mapContent)
Expand All @@ -116,40 +139,46 @@ func (DIDDocService) GetDIDFragment(fragmentId string, didDoc cheqd.Did) protoif
return nil
}

func (ds DIDDocService) prepareJWKPubkey(verificationMethod *cheqd.VerificationMethod) (map[string]interface{}, error) {
func (ds DIDDocService) prepareJWKPubkey(verificationMethod *cheqd.VerificationMethod) (orderedmap.OrderedMap, error) {
methodJson, err := ds.protoToMap(verificationMethod)
if err != nil {
return nil, err
return *orderedmap.New(), err
}
if len(verificationMethod.PublicKeyJwk) > 0 {
methodJson[publicKeyJwk] = cheqd.PubKeyJWKToMap(verificationMethod.PublicKeyJwk)
jsonKey, err := cheqd.PubKeyJWKToJson(verificationMethod.PublicKeyJwk)
if err != nil {
return *orderedmap.New(), err
}
methodJson.Set(publicKeyJwk, json.RawMessage(jsonKey))
}
return methodJson, nil
}

func (ds DIDDocService) MarshallVerificationMethod(verificationMethod []*cheqd.VerificationMethod) ([]map[string]interface{}, error) {
var verMethodList []map[string]interface{}
func (ds DIDDocService) MarshallVerificationMethod(verificationMethod []*cheqd.VerificationMethod) ([]byte, error) {
var verMethodList []orderedmap.OrderedMap
for _, value := range verificationMethod {
methodJson, err := ds.prepareJWKPubkey(value)
if err != nil {
return nil, err
return []byte{}, err
}
verMethodList = append(verMethodList, methodJson)
}
return verMethodList, nil
return json.Marshal(verMethodList)
}

func (ds DIDDocService) protoToMap(protoObject protoiface.MessageV1) (map[string]interface{}, error) {
func (ds DIDDocService) protoToMap(protoObject protoiface.MessageV1) (orderedmap.OrderedMap, error) {
mapObj := orderedmap.New()
jsonObj, err := ds.MarshallProto(protoObject)
if err != nil {
return nil, err
return *mapObj, err
}
var mapObj map[string]interface{}

//var mapObj map[string]interface{}

err = json.Unmarshal([]byte(jsonObj), &mapObj)
if err != nil {
return nil, err
return *mapObj, err
}

return mapObj, err
return *mapObj, err
}
6 changes: 3 additions & 3 deletions services/request_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,13 @@ func (rs RequestService) prepareDereferencingResult(did string, dereferencingOpt
return "", err
}

resolutionMetadata, err := json.Marshal(didDereferencing.DereferencingMetadata)
dereferencingMetadata, err := json.Marshal(didDereferencing.DereferencingMetadata)
if err != nil {
return "", err
}

if didDereferencing.DereferencingMetadata.ResolutionError != "" {
return createJsonDereferencing(nil, "", string(resolutionMetadata))
return createJsonDereferencing(nil, "", string(dereferencingMetadata))
}


Expand All @@ -94,7 +94,7 @@ func (rs RequestService) prepareDereferencingResult(did string, dereferencingOpt
return "", err
}

return createJsonDereferencing(didDereferencing.ContentStream, metadata, string(resolutionMetadata))
return createJsonDereferencing(didDereferencing.ContentStream, metadata, string(dereferencingMetadata))
}

// https://w3c-ccg.github.io/did-resolution/#resolving
Expand Down
99 changes: 53 additions & 46 deletions services/request_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,19 @@ const (
validNamespace = "mainnet"
validDid = "did:" + validMethod + ":" + validNamespace + ":" + validIdentifier
validResourceId = "a09abea0-22e0-4b35-8f70-9cc3a6d0b5fd"
validPubKeyJWK = "{" +
"\"crv\": \"Ed25519\"," +
"\"x\": \"VCpo2LMLhn6iWku8MKvSLg2ZAoC-nlOyPVQaO3FxVeQ\"," +
"\"kty\": \"OKP\"," +
"\"kid\": \"_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A\"" +
validPubKeyJWK = "{" +
"\"crv\":\"Ed25519\"," +
"\"kid\":\"_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A\"," +
"\"kty\":\"OKP\"," +
"\"x\":\"VCpo2LMLhn6iWku8MKvSLg2ZAoC-nlOyPVQaO3FxVeQ\"" +
"}"
)

func validVerificationMethod() cheqd.VerificationMethod {
return cheqd.VerificationMethod{
Id: validDid + "#key-1",
Type: "JsonWebKey2020",
Controller: validDid,
Id: validDid + "#key-1",
Type: "JsonWebKey2020",
Controller: validDid,
PublicKeyJwk: cheqd.JSONToPubKeyJWK(validPubKeyJWK),
}
}
Expand Down Expand Up @@ -180,10 +180,13 @@ func TestResolve(t *testing.T) {
t.Run(subtest.name, func(t *testing.T) {
requestService := NewRequestService("cheqd", subtest.ledgerService)
id := "did:" + subtest.method + ":" + subtest.namespace + ":" + subtest.identifier
expectedDIDProperties := types.DidProperties{
DidString: id,
MethodSpecificId: subtest.identifier,
Method: subtest.method,
expectedDIDProperties := types.DidProperties{}
if subtest.expectedError == "" {
expectedDIDProperties = types.DidProperties{
DidString: id,
MethodSpecificId: subtest.identifier,
Method: subtest.method,
}
}
if (subtest.resolutionType == types.DIDJSONLD || subtest.resolutionType == types.JSONLD) && subtest.expectedError == "" {
subtest.expectedDID.Context = []string{types.DIDSchemaJSONLD}
Expand All @@ -192,7 +195,8 @@ func TestResolve(t *testing.T) {
resolutionResult, err := requestService.Resolve(id, types.ResolutionOption{Accept: subtest.resolutionType})

fmt.Println(subtest.name + ": resolutionResult:")
fmt.Println(resolutionResult)
fmt.Println(resolutionResult.Did.VerificationMethod)
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)
Expand All @@ -208,6 +212,8 @@ func TestDereferencing(t *testing.T) {
validVerificationMethod := validVerificationMethod()
validService := validService()
validResource := validResource()
validChecksum, _ := json.Marshal(validResource.Header.Checksum)
validData, _ := json.Marshal(validResource.Data)
subtests := []struct {
name string
ledgerService MockLedgerService
Expand All @@ -218,43 +224,44 @@ func TestDereferencing(t *testing.T) {
expectedError types.ErrorType
}{
{
name: "successful resolution",
ledgerService: NewMockLedgerService(validDIDDoc, validMetadata(), validResource),
dereferencingType: types.DIDJSONLD,
didUrl: validDid,
expectedContentStream: fmt.Sprintf("{\"@context\": \"%s\",\"id\":\"%s\",\"verificationMethod\":[{\"controller\":\"%s\",\"id\":\"%s\",\"publicKeyJwk\":\"%s\",\"type\":\"%s\"}],\"service\":[{\"id\":\"%s\",\"serviceEndpoint\":\"%s\",\"type\":\"%s\"}]}",
types.DIDSchemaJSONLD, validDid, validVerificationMethod.Controller, validVerificationMethod.Id, validVerificationMethod.PublicKeyJwk, validVerificationMethod.Type, validService.Id, validService.ServiceEndpoint, validService.Type),
expectedMetadata: validMetadata(),
expectedError: "",
name: "successful resolution",
ledgerService: NewMockLedgerService(validDIDDoc, validMetadata(), validResource),
dereferencingType: types.DIDJSONLD,
didUrl: validDid,
expectedContentStream: fmt.Sprintf("{\"@context\":[\"%s\"],\"id\":\"%s\",\"verificationMethod\":[{\"id\":\"%s\",\"type\":\"%s\",\"controller\":\"%s\",\"publicKeyJwk\":%s}],\"service\":[{\"id\":\"%s\",\"type\":\"%s\",\"serviceEndpoint\":\"%s\"}]}",
types.DIDSchemaJSONLD, validDid, validVerificationMethod.Id, validVerificationMethod.Type, validVerificationMethod.Controller, validPubKeyJWK, validService.Id, validService.Type, validService.ServiceEndpoint),
expectedMetadata: validMetadata(),
expectedError: "",
},
{
name: "successful Secondary dereferencing (key)",
ledgerService: NewMockLedgerService(validDIDDoc, validMetadata(), validResource),
dereferencingType: types.DIDJSONLD,
didUrl: validVerificationMethod.Id,
expectedContentStream: fmt.Sprintf("{\"@context\": \"%s\",\"controller\":\"%s\",\"id\":\"%s\",\"publicKeyJwk\":\"%s\",\"type\":\"%s\"}",
types.DIDSchemaJSONLD, validVerificationMethod.Controller, validVerificationMethod.Id, validVerificationMethod.PublicKeyJwk, validVerificationMethod.Type),
expectedMetadata: validMetadata(),
expectedError: "",
name: "successful Secondary dereferencing (key)",
ledgerService: NewMockLedgerService(validDIDDoc, validMetadata(), validResource),
dereferencingType: types.DIDJSONLD,
didUrl: validVerificationMethod.Id,
expectedContentStream: fmt.Sprintf("{\"@context\":\"%s\",\"id\":\"%s\",\"type\":\"%s\",\"controller\":\"%s\",\"publicKeyJwk\":%s}",
types.DIDSchemaJSONLD, validVerificationMethod.Id, validVerificationMethod.Type, validVerificationMethod.Controller, validPubKeyJWK),
expectedMetadata: validMetadata(),
expectedError: "",
},
{
name: "successful Secondary dereferencing (service)",
ledgerService: NewMockLedgerService(validDIDDoc, validMetadata(), validResource),
dereferencingType: types.DIDJSONLD,
didUrl: validService.Id,
expectedContentStream: fmt.Sprintf("{\"@context\": \"%s\",\"id\":\"%s\",\"serviceEndpoint\":\"%s\",\"type\":\"%s\"}",
types.DIDSchemaJSONLD, validService.Id, validService.ServiceEndpoint, validService.Type),
expectedMetadata: validMetadata(),
expectedError: "",
name: "successful Secondary dereferencing (service)",
ledgerService: NewMockLedgerService(validDIDDoc, validMetadata(), validResource),
dereferencingType: types.DIDJSONLD,
didUrl: validService.Id,
expectedContentStream: fmt.Sprintf("{\"@context\":\"%s\",\"id\":\"%s\",\"type\":\"%s\",\"serviceEndpoint\":\"%s\"}",
types.DIDSchemaJSONLD, validService.Id, validService.Type, validService.ServiceEndpoint),
expectedMetadata: validMetadata(),
expectedError: "",
},
{
name: "successful Primary dereferencing (resource)",
ledgerService: NewMockLedgerService(validDIDDoc, validMetadata(), validResource),
dereferencingType: types.DIDJSONLD,
didUrl: validDid + "/resource/" + validResourceId,
expectedContentStream: "",
expectedMetadata: validMetadata(),
expectedError: "",
name: "successful Primary dereferencing (resource)",
ledgerService: NewMockLedgerService(validDIDDoc, validMetadata(), validResource),
dereferencingType: types.DIDJSONLD,
didUrl: validDid + "/resource/" + validResourceId,
expectedContentStream: fmt.Sprintf("{\"@context\":[\"%s\"],\"collectionId\":\"%s\",\"id\":\"%s\",\"name\":\"%s\",\"resourceType\":\"%s\",\"mediaType\":\"%s\",\"checksum\":%s,\"data\":%s}",
types.DIDSchemaJSONLD, validResource.Header.CollectionId, validResource.Header.Id, validResource.Header.Name, validResource.Header.ResourceType, validResource.Header.MediaType, validChecksum, validData),
expectedMetadata: cheqd.Metadata{},
expectedError: "",
},
{
name: "invalid URL",
Expand Down Expand Up @@ -310,10 +317,10 @@ func TestDereferencing(t *testing.T) {
fmt.Println(" dereferencingResult " + subtest.didUrl)

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

fmt.Println(subtest.name + ": dereferencingResult:")
fmt.Println(dereferencingResult)
require.EqualValues(t, json.RawMessage(subtest.expectedContentStream), json.RawMessage(dereferencingResult.ContentStream))
require.EqualValues(t, string(subtest.expectedContentStream), string(dereferencingResult.ContentStream))
require.EqualValues(t, subtest.expectedMetadata, dereferencingResult.Metadata)
require.EqualValues(t, subtest.dereferencingType, dereferencingResult.DereferencingMetadata.ContentType)
require.EqualValues(t, subtest.expectedError, dereferencingResult.DereferencingMetadata.ResolutionError)
Expand Down
18 changes: 11 additions & 7 deletions types/dereferencing_content_stream.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package types

import (
resource "github.com/cheqd/cheqd-node/x/resource/types"
)

type DereferencedResource struct {
Context []string
resource.ResourceHeader
Data []byte
Context []string `json:"@context,omitempty"`
CollectionId string `json:"collectionId,omitempty"`
Id string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
ResourceType string `json:"resourceType,omitempty"`
MediaType string `json:"mediaType,omitempty"`
Created string `json:"created,omitempty"`
Checksum []byte `json:"checksum,omitempty"`
PreviousVersionId string `json:"previousVersionId,omitempty"`
NextVersionId string `json:"nextVersionId,omitempty"`
Data []byte `json:"data,omitempty"`
}
19 changes: 12 additions & 7 deletions types/resolution_metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,21 @@ type DidResolution struct {
ResolutionMetadata ResolutionMetadata `json:"didResolutionMetadata,omitempty"`
}

func NewResolutionMetadata(did string, contentType ContentType, resolutionError ErrorType) ResolutionMetadata {
method, _, id, _ := cheqdUtils.TrySplitDID(did)
func NewResolutionMetadata(didUrl string, contentType ContentType, resolutionError ErrorType) ResolutionMetadata {
did, _, _, _, err1 := cheqdUtils.TrySplitDIDUrl(didUrl)
method, _, id, err2 := cheqdUtils.TrySplitDID(did)
var didProperties DidProperties
if err1 == nil && err2 == nil {
didProperties = DidProperties{
DidString: did,
MethodSpecificId: id,
Method: method,
}
}
return ResolutionMetadata{
ContentType: contentType,
ResolutionError: resolutionError,
Retrieved: time.Now().UTC().Format(time.RFC3339),
DidProperties: DidProperties{
DidString: did,
MethodSpecificId: id,
Method: method,
},
DidProperties: didProperties,
}
}
4 changes: 2 additions & 2 deletions utils/did_url.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import (
"regexp"
)

var ResourcePath, _ = regexp.Compile(`resource\\\[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}`)
var ResourcePath, _ = regexp.Compile(`resource\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}`)

func GetResourceId(didUrlPath string) (id string) {
if !ResourcePath.Match([]byte(didUrlPath)) {
return ""
}

match := ResourcePath.FindStringSubmatch(didUrlPath)
return match[1]
return match[0]
}

0 comments on commit da2ac42

Please sign in to comment.