From f2dc3f344c3b30bcc96e6aa1f495ce2623360611 Mon Sep 17 00:00:00 2001 From: toktar Date: Sat, 16 Jul 2022 12:35:33 +0300 Subject: [PATCH 1/9] Add resourcePreview to Metadata --- services/ledger_service.go | 25 +++++++++++++++++++++ services/request_service.go | 43 ++++++++++++++++++++++++++++++++---- types/resolution_metadata.go | 6 ++--- 3 files changed, 67 insertions(+), 7 deletions(-) diff --git a/services/ledger_service.go b/services/ledger_service.go index b7d0d60e..6e89ead5 100644 --- a/services/ledger_service.go +++ b/services/ledger_service.go @@ -20,6 +20,7 @@ import ( type LedgerServiceI interface { QueryDIDDoc(did string) (cheqd.Did, cheqd.Metadata, bool, error) QueryResource(collectionDid string, resourceId string) (resource.Resource, bool, error) + QueryCollectionResources(did string) ([]resource.ResourceHeader, error) GetNamespaces() []string } @@ -85,6 +86,30 @@ func (ls LedgerService) QueryResource(collectionDid string, resourceId string) ( return *resourceResponse.Resource, true, err } +func (ls LedgerService) QueryCollectionResources(did string) ([]*resource.ResourceHeader, error) { + _, namespace, _, _ := cheqdUtils.TrySplitDID(did) + serverAddr, namespaceFound := ls.ledgers[namespace] + if !namespaceFound { + return []*resource.ResourceHeader{}, fmt.Errorf("namespace not supported: %s", namespace) + } + + conn, err := ls.openGRPCConnection(serverAddr) + if err != nil { + log.Error().Err(err).Msg("QueryResource: failed connection") + return []*resource.ResourceHeader{}, err + } + + log.Info().Msgf("Querying did resource: %s", did) + + client := resource.NewQueryClient(conn) + resourceResponse, err := client.CollectionResources(context.Background(), &resource.QueryGetCollectionResourcesRequest{CollectionId: did}) + if err != nil { + return []*resource.ResourceHeader{}, err + } + + return resourceResponse.Resources, nil +} + func (ls *LedgerService) RegisterLedger(namespace string, url string) error { if namespace == "" { err := errors.New("namespace cannot be empty") diff --git a/services/request_service.go b/services/request_service.go index 4e706720..04fbc213 100644 --- a/services/request_service.go +++ b/services/request_service.go @@ -8,6 +8,7 @@ import ( "github.com/rs/zerolog/log" + cheqdTypes "github.com/cheqd/cheqd-node/x/cheqd/types" cheqdUtils "github.com/cheqd/cheqd-node/x/cheqd/utils" "github.com/cheqd/did-resolver/types" "github.com/cheqd/did-resolver/utils" @@ -59,16 +60,16 @@ func (rs RequestService) prepareResolutionResult(did string, resolutionOptions t return "", err } - metadata, err := rs.didDocService.MarshallProto(&didResolution.Metadata) + metadata, err := json.Marshal(&didResolution.Metadata) if err != nil { return "", err } if didResolution.ResolutionMetadata.ResolutionError != "" { - didDoc, metadata = "", "" + didDoc, metadata = "", []byte{} } - return createJsonResolution(didDoc, metadata, string(resolutionMetadata)) + return createJsonResolution(didDoc, string(metadata), string(resolutionMetadata)) } func (rs RequestService) prepareDereferencingResult(did string, dereferencingOptions types.DereferencingOption) (string, error) { @@ -117,6 +118,11 @@ func (rs RequestService) Resolve(did string, resolutionOptions types.ResolutionO return types.DidResolution{}, err } + resolvedMetadata, err := rs.ResolveMetadata(did, metadata) + if err != nil { + return types.DidResolution{}, err + } + if !isFound { didResolutionMetadata.ResolutionError = types.ResolutionNotFound return types.DidResolution{ResolutionMetadata: didResolutionMetadata}, nil @@ -125,7 +131,7 @@ func (rs RequestService) Resolve(did string, resolutionOptions types.ResolutionO if didResolutionMetadata.ContentType == types.DIDJSONLD { didDoc.Context = append(didDoc.Context, types.DIDSchemaJSONLD) } - return types.DidResolution{Did: didDoc, Metadata: metadata, ResolutionMetadata: didResolutionMetadata}, nil + return types.DidResolution{Did: didDoc, Metadata: resolvedMetadata, ResolutionMetadata: didResolutionMetadata}, nil } // https://w3c-ccg.github.io/did-resolution/#dereferencing @@ -216,6 +222,35 @@ func (rs RequestService) dereferenceSecondary(did string, fragmentId string, did return types.DidDereferencing{ContentStream: contentStream, Metadata: didResolution.Metadata, DereferencingMetadata: dereferencingMetadata}, nil } +func (rs RequestService) ResolveMetadata(did string, metadata cheqdTypes.Metadata) (types.ResolutionDidDocMetadata, error) { + newMetadata := types.ResolutionDidDocMetadata{ + metadata.Created, + metadata.Updated, + metadata.Deactivated, + metadata.VersionId, + []types.ResourcePreview{}, + } + if metadata.Resources != nil { + return newMetadata, nil + } + resources, err := rs.ledgerService.QueryCollectionResources(did) + if err != nil { + return newMetadata, err + } + for _, r := range resources { + resourcePreview := types.ResourcePreview { + r.Id, + r.Name, + r.ResourceType, + r.MediaType, + r.Created, + } + newMetadata.Resources = append(newMetadata.Resources, resourcePreview) + } + return newMetadata, nil + +} + func createJsonResolution(didDoc string, metadata string, resolutionMetadata string) (string, error) { if didDoc == "" { didDoc = "null" diff --git a/types/resolution_metadata.go b/types/resolution_metadata.go index 19d8a794..edbbd7db 100644 --- a/types/resolution_metadata.go +++ b/types/resolution_metadata.go @@ -25,9 +25,9 @@ type DidProperties struct { } type DidResolution struct { - Did cheqd.Did `json:"didDocument,omitempty"` - Metadata cheqd.Metadata `json:"didDocumentMetadata,omitempty"` - ResolutionMetadata ResolutionMetadata `json:"didResolutionMetadata,omitempty"` + Did cheqd.Did `json:"didDocument,omitempty"` + Metadata ResolutionDidDocMetadata `json:"didDocumentMetadata,omitempty"` + ResolutionMetadata ResolutionMetadata `json:"didResolutionMetadata,omitempty"` } func NewResolutionMetadata(didUrl string, contentType ContentType, resolutionError ErrorType) ResolutionMetadata { From d73873abdf5877df34f3474204b54a0c2dca00e3 Mon Sep 17 00:00:00 2001 From: toktar Date: Sat, 16 Jul 2022 15:44:36 +0300 Subject: [PATCH 2/9] Update unit tests and dereferencing structure --- services/ledger_service.go | 2 +- services/request_service.go | 36 +++++++-------------- services/request_service_test.go | 54 +++++++++++++++++++------------- types/dereferecing_metadata.go | 8 ++--- 4 files changed, 48 insertions(+), 52 deletions(-) diff --git a/services/ledger_service.go b/services/ledger_service.go index 6e89ead5..09bce950 100644 --- a/services/ledger_service.go +++ b/services/ledger_service.go @@ -20,7 +20,7 @@ import ( type LedgerServiceI interface { QueryDIDDoc(did string) (cheqd.Did, cheqd.Metadata, bool, error) QueryResource(collectionDid string, resourceId string) (resource.Resource, bool, error) - QueryCollectionResources(did string) ([]resource.ResourceHeader, error) + QueryCollectionResources(did string) ([]*resource.ResourceHeader, error) GetNamespaces() []string } diff --git a/services/request_service.go b/services/request_service.go index 04fbc213..b0410579 100644 --- a/services/request_service.go +++ b/services/request_service.go @@ -9,6 +9,7 @@ import ( "github.com/rs/zerolog/log" cheqdTypes "github.com/cheqd/cheqd-node/x/cheqd/types" + resourceTypes "github.com/cheqd/cheqd-node/x/resource/types" cheqdUtils "github.com/cheqd/cheqd-node/x/cheqd/utils" "github.com/cheqd/did-resolver/types" "github.com/cheqd/did-resolver/utils" @@ -89,12 +90,12 @@ func (rs RequestService) prepareDereferencingResult(did string, dereferencingOpt return createJsonDereferencing(nil, "", string(dereferencingMetadata)) } - metadata, err := rs.didDocService.MarshallProto(&didDereferencing.Metadata) + metadata, err := json.Marshal(didDereferencing.Metadata) if err != nil { return "", err } - return createJsonDereferencing(didDereferencing.ContentStream, metadata, string(dereferencingMetadata)) + return createJsonDereferencing(didDereferencing.ContentStream, string(metadata), string(dereferencingMetadata)) } // https://w3c-ccg.github.io/did-resolution/#resolving @@ -196,6 +197,7 @@ func (rs RequestService) dereferenceSecondary(did string, fragmentId string, did if err != nil { return types.DidDereferencing{}, err } + metadata := didResolution.Metadata dereferencingMetadata := types.DereferencingMetadata(didResolution.ResolutionMetadata) if dereferencingMetadata.ResolutionError != "" { return types.DidDereferencing{DereferencingMetadata: dereferencingMetadata}, nil @@ -204,6 +206,7 @@ func (rs RequestService) dereferenceSecondary(did string, fragmentId string, did var protoContent protoiface.MessageV1 if fragmentId != "" { protoContent = rs.didDocService.GetDIDFragment(fragmentId, didResolution.Did) + metadata = types.TransformToFragmentMetadata(metadata) } else { protoContent = &didResolution.Did } @@ -219,35 +222,18 @@ func (rs RequestService) dereferenceSecondary(did string, fragmentId string, did } contentStream := json.RawMessage(jsonFragment) - return types.DidDereferencing{ContentStream: contentStream, Metadata: didResolution.Metadata, DereferencingMetadata: dereferencingMetadata}, nil + return types.DidDereferencing{ContentStream: contentStream, Metadata: metadata, DereferencingMetadata: dereferencingMetadata}, nil } func (rs RequestService) ResolveMetadata(did string, metadata cheqdTypes.Metadata) (types.ResolutionDidDocMetadata, error) { - newMetadata := types.ResolutionDidDocMetadata{ - metadata.Created, - metadata.Updated, - metadata.Deactivated, - metadata.VersionId, - []types.ResourcePreview{}, - } - if metadata.Resources != nil { - return newMetadata, nil + if metadata.Resources == nil { + return types.NewResolutionDidDocMetadata(metadata, []*resourceTypes.ResourceHeader{}), nil } resources, err := rs.ledgerService.QueryCollectionResources(did) if err != nil { - return newMetadata, err - } - for _, r := range resources { - resourcePreview := types.ResourcePreview { - r.Id, - r.Name, - r.ResourceType, - r.MediaType, - r.Created, - } - newMetadata.Resources = append(newMetadata.Resources, resourcePreview) - } - return newMetadata, nil + return types.ResolutionDidDocMetadata{}, err + } + return types.NewResolutionDidDocMetadata(metadata, resources), nil } diff --git a/services/request_service_test.go b/services/request_service_test.go index 30ff2902..33a9dd97 100644 --- a/services/request_service_test.go +++ b/services/request_service_test.go @@ -103,12 +103,22 @@ func (ls MockLedgerService) QueryResource(collectionDid string, resourceId strin return ls.Resource, isFound, nil } + +func (ls MockLedgerService) QueryCollectionResources(did string) ([]*resource.ResourceHeader, error) { + if ls.Metadata.Resources == nil { + return []*resource.ResourceHeader{}, nil + } + return []*resource.ResourceHeader{ls.Resource.Header}, nil +} + func (ls MockLedgerService) GetNamespaces() []string { return []string{"testnet", "mainnet"} } func TestResolve(t *testing.T) { validDIDDoc := validDIDDoc() + validMetadata := validMetadata() + validResource := validResource() subtests := []struct { name string ledgerService MockLedgerService @@ -117,18 +127,18 @@ func TestResolve(t *testing.T) { method string namespace string expectedDID cheqd.Did - expectedMetadata cheqd.Metadata + expectedMetadata types.ResolutionDidDocMetadata expectedError types.ErrorType }{ { name: "successful resolution", - ledgerService: NewMockLedgerService(validDIDDoc, validMetadata(), resource.Resource{}), + ledgerService: NewMockLedgerService(validDIDDoc, validMetadata, validResource), resolutionType: types.DIDJSONLD, identifier: validIdentifier, method: validMethod, namespace: validNamespace, expectedDID: validDIDDoc, - expectedMetadata: validMetadata(), + expectedMetadata: types.NewResolutionDidDocMetadata(validMetadata, []*resource.ResourceHeader{validResource.Header}), expectedError: "", }, { @@ -139,7 +149,7 @@ func TestResolve(t *testing.T) { method: validMethod, namespace: validNamespace, expectedDID: cheqd.Did{}, - expectedMetadata: cheqd.Metadata{}, + expectedMetadata: types.ResolutionDidDocMetadata{}, expectedError: types.ResolutionNotFound, }, { @@ -150,7 +160,7 @@ func TestResolve(t *testing.T) { method: validMethod, namespace: validNamespace, expectedDID: cheqd.Did{}, - expectedMetadata: cheqd.Metadata{}, + expectedMetadata: types.ResolutionDidDocMetadata{}, expectedError: types.ResolutionInvalidDID, }, { @@ -161,7 +171,7 @@ func TestResolve(t *testing.T) { method: "not_supported_method", namespace: validNamespace, expectedDID: cheqd.Did{}, - expectedMetadata: cheqd.Metadata{}, + expectedMetadata: types.ResolutionDidDocMetadata{}, expectedError: types.ResolutionMethodNotSupported, }, { @@ -172,7 +182,7 @@ func TestResolve(t *testing.T) { method: validMethod, namespace: "invalid_namespace", expectedDID: cheqd.Did{}, - expectedMetadata: cheqd.Metadata{}, + expectedMetadata: types.ResolutionDidDocMetadata{}, expectedError: types.ResolutionInvalidDID, }, } @@ -212,53 +222,55 @@ func TestDereferencing(t *testing.T) { validResource := validResource() validChecksum, _ := json.Marshal(validResource.Header.Checksum) validData, _ := json.Marshal(validResource.Data) + validMetadata := validMetadata() + validFragmentMetadata := types.NewResolutionDidDocMetadata(validMetadata, []*resource.ResourceHeader{}) subtests := []struct { name string ledgerService MockLedgerService dereferencingType types.ContentType didUrl string expectedContentStream string - expectedMetadata cheqd.Metadata + expectedMetadata types.ResolutionDidDocMetadata expectedError types.ErrorType }{ { name: "successful resolution", - ledgerService: NewMockLedgerService(validDIDDoc, validMetadata(), validResource), + 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(), + expectedMetadata: types.NewResolutionDidDocMetadata(validMetadata, []*resource.ResourceHeader{validResource.Header}), expectedError: "", }, { name: "successful Secondary dereferencing (key)", - ledgerService: NewMockLedgerService(validDIDDoc, validMetadata(), validResource), + 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(), + expectedMetadata: validFragmentMetadata, expectedError: "", }, { name: "successful Secondary dereferencing (service)", - ledgerService: NewMockLedgerService(validDIDDoc, validMetadata(), validResource), + 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(), + expectedMetadata: validFragmentMetadata, expectedError: "", }, { name: "successful Primary dereferencing (resource)", - ledgerService: NewMockLedgerService(validDIDDoc, validMetadata(), validResource), + 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{}, + expectedMetadata: types.ResolutionDidDocMetadata{}, expectedError: "", }, { @@ -266,7 +278,7 @@ func TestDereferencing(t *testing.T) { ledgerService: NewMockLedgerService(cheqd.Did{}, cheqd.Metadata{}, resource.Resource{}), didUrl: "unvalid_url", dereferencingType: types.DIDJSONLD, - expectedMetadata: cheqd.Metadata{}, + expectedMetadata: types.ResolutionDidDocMetadata{}, expectedError: types.DereferencingInvalidDIDUrl, }, { @@ -274,7 +286,7 @@ func TestDereferencing(t *testing.T) { ledgerService: NewMockLedgerService(cheqd.Did{}, cheqd.Metadata{}, resource.Resource{}), dereferencingType: types.DIDJSONLD, didUrl: validDid + "/unknown_path", - expectedMetadata: cheqd.Metadata{}, + expectedMetadata: types.ResolutionDidDocMetadata{}, expectedError: types.DereferencingNotSupported, }, { @@ -282,7 +294,7 @@ func TestDereferencing(t *testing.T) { ledgerService: NewMockLedgerService(cheqd.Did{}, cheqd.Metadata{}, resource.Resource{}), dereferencingType: types.DIDJSONLD, didUrl: validDid + "?unknown_query", - expectedMetadata: cheqd.Metadata{}, + expectedMetadata: types.ResolutionDidDocMetadata{}, expectedError: types.DereferencingNotSupported, }, { @@ -290,7 +302,7 @@ func TestDereferencing(t *testing.T) { ledgerService: NewMockLedgerService(cheqd.Did{}, cheqd.Metadata{}, resource.Resource{}), dereferencingType: types.DIDJSONLD, didUrl: validDid + "#notFoundKey", - expectedMetadata: cheqd.Metadata{}, + expectedMetadata: types.ResolutionDidDocMetadata{}, expectedError: types.DereferencingNotFound, }, { @@ -298,7 +310,7 @@ func TestDereferencing(t *testing.T) { ledgerService: NewMockLedgerService(cheqd.Did{}, cheqd.Metadata{}, resource.Resource{}), dereferencingType: types.DIDJSONLD, didUrl: validDid + "/resource/00000000-0000-0000-0000-000000000000", - expectedMetadata: cheqd.Metadata{}, + expectedMetadata: types.ResolutionDidDocMetadata{}, expectedError: types.DereferencingNotFound, }, } diff --git a/types/dereferecing_metadata.go b/types/dereferecing_metadata.go index d6a624fa..c0f9fe99 100644 --- a/types/dereferecing_metadata.go +++ b/types/dereferecing_metadata.go @@ -2,8 +2,6 @@ package types import ( "encoding/json" - - cheqd "github.com/cheqd/cheqd-node/x/cheqd/types" ) type DereferencingOption ResolutionOption @@ -11,9 +9,9 @@ type DereferencingOption ResolutionOption type DereferencingMetadata ResolutionMetadata type DidDereferencing struct { - ContentStream json.RawMessage `json:"contentStream,omitempty"` - Metadata cheqd.Metadata `json:"contentMetadata,omitempty"` - DereferencingMetadata DereferencingMetadata `json:"dereferencingMetadata,omitempty"` + ContentStream json.RawMessage `json:"contentStream,omitempty"` + Metadata ResolutionDidDocMetadata `json:"contentMetadata,omitempty"` + DereferencingMetadata DereferencingMetadata `json:"dereferencingMetadata,omitempty"` } func NewDereferencingMetadata(did string, contentType ContentType, resolutionError ErrorType) DereferencingMetadata { From 5035c9c98ff1acf16bc8251583888d6d76c93cdb Mon Sep 17 00:00:00 2001 From: toktar Date: Tue, 19 Jul 2022 00:55:53 +0300 Subject: [PATCH 3/9] add metadata model --- types/did_doc_metadata.go | 55 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 types/did_doc_metadata.go diff --git a/types/did_doc_metadata.go b/types/did_doc_metadata.go new file mode 100644 index 00000000..96987b7b --- /dev/null +++ b/types/did_doc_metadata.go @@ -0,0 +1,55 @@ +package types + +import ( + cheqd "github.com/cheqd/cheqd-node/x/cheqd/types" + resource "github.com/cheqd/cheqd-node/x/resource/types" +) + +type ResolutionDidDocMetadata struct { + Created string `json:"created,omitempty"` + Updated string `json:"updated,omitempty"` + Deactivated bool `json:"deactivated,omitempty"` + VersionId string `json:"versionId,omitempty"` + Resources []ResourcePreview `json:"resources,omitempty"` +} + +type ResourcePreview struct { + 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"` +} + + +func NewResolutionDidDocMetadata(metadata cheqd.Metadata, resources []*resource.ResourceHeader) ResolutionDidDocMetadata { + newMetadata := ResolutionDidDocMetadata{ + metadata.Created, + metadata.Updated, + metadata.Deactivated, + metadata.VersionId, + []ResourcePreview(nil), + } + if metadata.Resources == nil { + return newMetadata + } + for _, r := range resources { + resourcePreview := ResourcePreview { + r.Id, + r.Name, + r.ResourceType, + r.MediaType, + r.Created, + } + newMetadata.Resources = append(newMetadata.Resources, resourcePreview) + } + return newMetadata +} + +func TransformToFragmentMetadata(metadata ResolutionDidDocMetadata) ResolutionDidDocMetadata { + metadata.Resources = nil + return metadata +} + + + From f85d3271875cc847db894f21ab1efd5fc3db2921 Mon Sep 17 00:00:00 2001 From: toktar Date: Tue, 19 Jul 2022 01:48:17 +0300 Subject: [PATCH 4/9] update tests --- tests/pytest/helpers.py | 5 +++-- tests/pytest/test_resolution.py | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/pytest/helpers.py b/tests/pytest/helpers.py index fa487b6a..8feda6f0 100644 --- a/tests/pytest/helpers.py +++ b/tests/pytest/helpers.py @@ -7,10 +7,11 @@ RESOLVER_URL = "http://localhost:1313" PATH = "/1.0/identifiers/" -TESTNET_DID = "did:cheqd:testnet:zFWM1mKVGGU2gHYuLAQcTJfZBebqBpGf" +TESTNET_DID = "did:cheqd:testnet:DAzMQo4MDMxCjgwM" TESTNET_FRAGMENT = TESTNET_DID + "#key1" FAKE_TESTNET_DID = "did:cheqd:testnet:zF7rhDBfUt9d1gJPjx7s1JXfUY7oVWkY" -TESTNET_RESOURCE = "did:cheqd:testnet:DAzMQo4MDMxCjgwM" + "/resources/44547089-170b-4f5a-bcbc-06e46e0089e4" +TESTNET_RESOURCE = TESTNET_DID + "/resources/44547089-170b-4f5a-bcbc-06e46e0089e4" +TESTNET_RESOURCE_NAME = "Demo Resource" FAKE_TESTNET_FRAGMENT = TESTNET_DID + "#fake_key" FAKE_TESTNET_RESOURCE = TESTNET_DID + "/resources/76471e8c-0d1c-4b97-9b11-17b65e024334" diff --git a/tests/pytest/test_resolution.py b/tests/pytest/test_resolution.py index 2115f33d..21528491 100644 --- a/tests/pytest/test_resolution.py +++ b/tests/pytest/test_resolution.py @@ -5,13 +5,13 @@ 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 + LDJSON, DIDJSON, DIDLDJSON, HTML, FAKE_TESTNET_RESOURCE, TESTNET_RESOURCE, TESTNET_RESOURCE_NAME @pytest.mark.parametrize( "did_url, expected_output", [ - (TESTNET_DID, fr"didResolutionMetadata(.*?)didDocument(.*?)\"id\":\"{TESTNET_DID}\"(.*?)didDocumentMetadata"), + (TESTNET_DID, fr"didResolutionMetadata(.*?)didDocument(.*?)\"id\":\"{TESTNET_DID}\"(.*?){TESTNET_RESOURCE_NAME}(.*?)didDocumentMetadata"), (MAINNET_DID, fr"didResolutionMetadata(.*?)didDocument(.*?)\"id\":\"{MAINNET_DID}\"(.*?)didDocumentMetadata"), (FAKE_TESTNET_DID, r"\"didResolutionMetadata(.*?)\"error\":\"notFound\"(.*?)" r"didDocument\":null,\"didDocumentMetadata\":\[\]"), From 3dc673bdb3e293dfaf7504fa57edfe246d113396 Mon Sep 17 00:00:00 2001 From: toktar Date: Tue, 19 Jul 2022 03:46:17 +0300 Subject: [PATCH 5/9] fix: resource context --- services/diddoc_service.go | 12 ++--- tests/pytest/test_resolution.py | 85 ++++++++++++++++++++++++++++----- 2 files changed, 78 insertions(+), 19 deletions(-) diff --git a/services/diddoc_service.go b/services/diddoc_service.go index adf06f16..e349f622 100644 --- a/services/diddoc_service.go +++ b/services/diddoc_service.go @@ -64,16 +64,16 @@ func (ds DIDDocService) MarshallDID(didDoc cheqd.Did) (string, error) { func (ds DIDDocService) MarshallContentStream(contentStream protoiface.MessageV1, contentType types.ContentType) (string, error) { var mapContent orderedmap.OrderedMap var err error - var context types.ContentType + var context []string if contentType == types.DIDJSONLD || contentType == types.JSONLD { - context = types.DIDSchemaJSONLD + context = []string{types.DIDSchemaJSONLD} } switch contentStream := contentStream.(type) { case *cheqd.VerificationMethod: mapContent, err = ds.prepareJWKPubkey(contentStream) case *cheqd.Did: - contentStream.Context = []string{string(context)} + contentStream.Context = context jsonDid, err := ds.MarshallDID(*contentStream) if err != nil { return "", err @@ -81,7 +81,7 @@ func (ds DIDDocService) MarshallContentStream(contentStream protoiface.MessageV1 return string(jsonDid), nil case *resource.Resource: dResource := types.DereferencedResource{ - Context: []string{string(context)}, + Context: context, CollectionId: contentStream.Header.CollectionId, Id: contentStream.Header.Id, Name: contentStream.Header.Name, @@ -107,8 +107,8 @@ func (ds DIDDocService) MarshallContentStream(contentStream protoiface.MessageV1 } // Context changes - if context != "" { - mapContent.Set("@"+didContext, context) + if len(context) != 0 { + mapContent.Set("@"+didContext, context[0]) mapContent.Sort(func(a *orderedmap.Pair, b *orderedmap.Pair) bool { return a.Key() == "@"+didContext }) diff --git a/tests/pytest/test_resolution.py b/tests/pytest/test_resolution.py index 2115f33d..b57e0d2f 100644 --- a/tests/pytest/test_resolution.py +++ b/tests/pytest/test_resolution.py @@ -30,7 +30,7 @@ r"\"dereferencingMetadata(.*?)\"error\":\"notFound\""), (TESTNET_RESOURCE, fr"\"contentStream\":(.*?)collectionId(.*?),\"contentMetadata\":(.*?)," - r"\"dereferencingMetadata(.*?)"), + r"\"dereferencingMetadata(.*?)"), (FAKE_TESTNET_RESOURCE, r"\"contentStream\":null,\"contentMetadata\":\[\]," r"\"dereferencingMetadata(.*?)\"error\":\"notFound\""), ] @@ -40,21 +40,21 @@ def test_resolution(did_url, expected_output): @pytest.mark.parametrize( - "accept, expected_header, expected_body", + "accept, expected_header, has_context, expected_body", [ - (LDJSON, LDJSON, r"(.*?)didResolutionMetadata(.*?)application/ld\+json" - r"(.*?)didDocument(.*?)@context(.*?)didDocumentMetadata"), - (DIDLDJSON, DIDLDJSON, "(.*?)didResolutionMetadata(.*?)application/did\+ld\+json" - "(.*?)didDocument(.*?)@context(.*?)didDocumentMetadata"), - ("", DIDLDJSON, "(.*?)didResolutionMetadata(.*?)application/did\+ld\+json" - "(.*?)didDocument(.*?)@context(.*?)didDocumentMetadata"), - (DIDJSON, DIDJSON, r"(.*?)didResolutionMetadata(.*?)application/did\+json" - r"(.*?)didDocument(.*?)(?!`@context`)(.*?)didDocumentMetadata"), - (HTML + ",application/xhtml+xml", HTML, fr"(.*?)didResolutionMetadata(.*?){HTML}" - fr"(.*?)didDocument(.*?)(?!`@context`)(.*?)didDocumentMetadata"), + (LDJSON, LDJSON, True, r"(.*?)didResolutionMetadata(.*?)application/ld\+json" + 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"), + (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"), ] ) -def test_resolution_content_type(accept, expected_header, expected_body): +def test_resolution_content_type(accept, expected_header, expected_body, has_context): url = RESOLVER_URL + PATH + TESTNET_DID header = {"Accept": accept} if accept else {} @@ -62,3 +62,62 @@ def test_resolution_content_type(accept, expected_header, expected_body): assert r.headers["Content-Type"] == expected_header assert re.match(expected_body, r.text) + if has_context: + assert re.findall(r"context", r.text) + else: + assert not re.findall(r"context", r.text) + + +dereferencing_content_type_test_set = [ + (LDJSON, LDJSON, True, + r"(.*?)contentStream(.*?)@context(.*?)contentMetadata" + r"(.*?)dereferencingMetadata(.*?)application/ld\+json"), + (DIDLDJSON, DIDLDJSON, True, + "(.*?)contentStream(.*?)@context(.*?)contentMetadata" + "(.*?)dereferencingMetadata(.*?)application/did\+ld\+json"), + ("", 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}"), +] + + +@pytest.mark.parametrize( + "accept, expected_header, has_context, expected_body", + dereferencing_content_type_test_set +) +def test_dereferencing_content_type_fragment(accept, expected_header, expected_body, has_context): + url = RESOLVER_URL + PATH + TESTNET_RESOURCE + header = {"Accept": accept} if accept else {} + + r = requests.get(url, headers=header) + + assert r.headers["Content-Type"] == expected_header + assert re.match(expected_body, r.text) + if has_context: + assert re.findall(r"context", r.text) + else: + assert not re.findall(r"context", r.text) + + +@pytest.mark.parametrize( + "accept, expected_header, has_context, expected_body", + dereferencing_content_type_test_set +) +def test_dereferencing_content_type_resource(accept, expected_header, expected_body, has_context): + url = RESOLVER_URL + PATH + TESTNET_FRAGMENT.replace("#", "%23") + header = {"Accept": accept} if accept else {} + + r = requests.get(url, headers=header) + + assert r.headers["Content-Type"] == expected_header + assert re.match(expected_body, r.text) + if has_context: + assert re.findall(r"context", r.text) + else: + assert not re.findall(r"context", r.text) From bce649345fc481a920ed95caba1194b2d2d3ab7d Mon Sep 17 00:00:00 2001 From: toktar Date: Tue, 19 Jul 2022 04:36:16 +0300 Subject: [PATCH 6/9] update tests --- services/ledger_service.go | 4 ++-- tests/pytest/test_resolution.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/services/ledger_service.go b/services/ledger_service.go index f06b6dfc..2384147f 100644 --- a/services/ledger_service.go +++ b/services/ledger_service.go @@ -92,7 +92,7 @@ func (ls LedgerService) QueryResource(did string, resourceId string) (resource.R } func (ls LedgerService) QueryCollectionResources(did string) ([]*resource.ResourceHeader, error) { - _, namespace, _, _ := cheqdUtils.TrySplitDID(did) + _, namespace, collectionId, _ := cheqdUtils.TrySplitDID(did) serverAddr, namespaceFound := ls.ledgers[namespace] if !namespaceFound { return []*resource.ResourceHeader{}, fmt.Errorf("namespace not supported: %s", namespace) @@ -107,7 +107,7 @@ func (ls LedgerService) QueryCollectionResources(did string) ([]*resource.Resour log.Info().Msgf("Querying did resource: %s", did) client := resource.NewQueryClient(conn) - resourceResponse, err := client.CollectionResources(context.Background(), &resource.QueryGetCollectionResourcesRequest{CollectionId: did}) + resourceResponse, err := client.CollectionResources(context.Background(), &resource.QueryGetCollectionResourcesRequest{CollectionId: collectionId}) if err != nil { return []*resource.ResourceHeader{}, err } diff --git a/tests/pytest/test_resolution.py b/tests/pytest/test_resolution.py index 173cc7a8..34b329c2 100644 --- a/tests/pytest/test_resolution.py +++ b/tests/pytest/test_resolution.py @@ -11,7 +11,7 @@ @pytest.mark.parametrize( "did_url, expected_output", [ - (TESTNET_DID, fr"didResolutionMetadata(.*?)didDocument(.*?)\"id\":\"{TESTNET_DID}\"(.*?){TESTNET_RESOURCE_NAME}(.*?)didDocumentMetadata"), + (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\":\[\]"), From 83ed95722d733627d0c445ade57a5bbfd45674b9 Mon Sep 17 00:00:00 2001 From: toktar Date: Tue, 19 Jul 2022 17:56:26 +0300 Subject: [PATCH 7/9] lint fix --- services/request_service.go | 3 +-- services/request_service_test.go | 1 - types/did_doc_metadata.go | 23 ++++++++++------------- 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/services/request_service.go b/services/request_service.go index c1889371..8c18bbbb 100644 --- a/services/request_service.go +++ b/services/request_service.go @@ -9,8 +9,8 @@ import ( "github.com/rs/zerolog/log" cheqdTypes "github.com/cheqd/cheqd-node/x/cheqd/types" - resourceTypes "github.com/cheqd/cheqd-node/x/resource/types" cheqdUtils "github.com/cheqd/cheqd-node/x/cheqd/utils" + resourceTypes "github.com/cheqd/cheqd-node/x/resource/types" "github.com/cheqd/did-resolver/types" "github.com/cheqd/did-resolver/utils" "google.golang.org/protobuf/runtime/protoiface" @@ -245,7 +245,6 @@ func (rs RequestService) ResolveMetadata(did string, metadata cheqdTypes.Metadat return types.ResolutionDidDocMetadata{}, err } return types.NewResolutionDidDocMetadata(metadata, resources), nil - } func createJsonResolution(didDoc string, metadata string, resolutionMetadata string) (string, error) { diff --git a/services/request_service_test.go b/services/request_service_test.go index 57ede8eb..1f3c1c89 100644 --- a/services/request_service_test.go +++ b/services/request_service_test.go @@ -103,7 +103,6 @@ func (ls MockLedgerService) QueryResource(did string, resourceId string) (resour return ls.Resource, isFound, nil } - func (ls MockLedgerService) QueryCollectionResources(did string) ([]*resource.ResourceHeader, error) { if ls.Metadata.Resources == nil { return []*resource.ResourceHeader{}, nil diff --git a/types/did_doc_metadata.go b/types/did_doc_metadata.go index 96987b7b..65cd85d6 100644 --- a/types/did_doc_metadata.go +++ b/types/did_doc_metadata.go @@ -6,22 +6,21 @@ import ( ) type ResolutionDidDocMetadata struct { - Created string `json:"created,omitempty"` - Updated string `json:"updated,omitempty"` - Deactivated bool `json:"deactivated,omitempty"` - VersionId string `json:"versionId,omitempty"` + Created string `json:"created,omitempty"` + Updated string `json:"updated,omitempty"` + Deactivated bool `json:"deactivated,omitempty"` + VersionId string `json:"versionId,omitempty"` Resources []ResourcePreview `json:"resources,omitempty"` } type ResourcePreview struct { - 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"` + 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"` } - func NewResolutionDidDocMetadata(metadata cheqd.Metadata, resources []*resource.ResourceHeader) ResolutionDidDocMetadata { newMetadata := ResolutionDidDocMetadata{ metadata.Created, @@ -34,7 +33,7 @@ func NewResolutionDidDocMetadata(metadata cheqd.Metadata, resources []*resource. return newMetadata } for _, r := range resources { - resourcePreview := ResourcePreview { + resourcePreview := ResourcePreview{ r.Id, r.Name, r.ResourceType, @@ -51,5 +50,3 @@ func TransformToFragmentMetadata(metadata ResolutionDidDocMetadata) ResolutionDi return metadata } - - From b6b2fe4a99504c5bf4b9762c872fe4204ec49e70 Mon Sep 17 00:00:00 2001 From: toktar Date: Fri, 22 Jul 2022 13:57:35 +0300 Subject: [PATCH 8/9] lint fix --- types/did_doc_metadata.go | 1 - 1 file changed, 1 deletion(-) diff --git a/types/did_doc_metadata.go b/types/did_doc_metadata.go index 65cd85d6..58681714 100644 --- a/types/did_doc_metadata.go +++ b/types/did_doc_metadata.go @@ -49,4 +49,3 @@ func TransformToFragmentMetadata(metadata ResolutionDidDocMetadata) ResolutionDi metadata.Resources = nil return metadata } - From 1fc1674bc70447cd038d457e3460d2a0238f4cf5 Mon Sep 17 00:00:00 2001 From: toktar Date: Tue, 26 Jul 2022 13:00:03 +0300 Subject: [PATCH 9/9] Add ResourceURI to DID Doc metadata --- services/request_service.go | 4 ++-- services/request_service_test.go | 10 +++++----- types/constants.go | 4 ++++ types/did_doc_metadata.go | 6 +++--- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/services/request_service.go b/services/request_service.go index 8c18bbbb..3b59c072 100644 --- a/services/request_service.go +++ b/services/request_service.go @@ -238,13 +238,13 @@ func (rs RequestService) dereferenceSecondary(did string, fragmentId string, did func (rs RequestService) ResolveMetadata(did string, metadata cheqdTypes.Metadata) (types.ResolutionDidDocMetadata, error) { if metadata.Resources == nil { - return types.NewResolutionDidDocMetadata(metadata, []*resourceTypes.ResourceHeader{}), nil + return types.NewResolutionDidDocMetadata(did, metadata, []*resourceTypes.ResourceHeader{}), nil } resources, err := rs.ledgerService.QueryCollectionResources(did) if err != nil { return types.ResolutionDidDocMetadata{}, err } - return types.NewResolutionDidDocMetadata(metadata, resources), nil + return types.NewResolutionDidDocMetadata(did, metadata, resources), nil } func createJsonResolution(didDoc string, metadata string, resolutionMetadata string) (string, error) { diff --git a/services/request_service_test.go b/services/request_service_test.go index 1f3c1c89..1fad69a1 100644 --- a/services/request_service_test.go +++ b/services/request_service_test.go @@ -137,7 +137,7 @@ func TestResolve(t *testing.T) { method: validMethod, namespace: validNamespace, expectedDID: validDIDDoc, - expectedMetadata: types.NewResolutionDidDocMetadata(validMetadata, []*resource.ResourceHeader{validResource.Header}), + expectedMetadata: types.NewResolutionDidDocMetadata(validDid, validMetadata, []*resource.ResourceHeader{validResource.Header}), expectedError: "", }, { @@ -224,7 +224,7 @@ func TestDereferencing(t *testing.T) { validChecksum, _ := json.Marshal(validResource.Header.Checksum) validData, _ := json.Marshal(validResource.Data) validMetadata := validMetadata() - validFragmentMetadata := types.NewResolutionDidDocMetadata(validMetadata, []*resource.ResourceHeader{}) + validFragmentMetadata := types.NewResolutionDidDocMetadata(validDid, validMetadata, []*resource.ResourceHeader{}) subtests := []struct { name string ledgerService MockLedgerService @@ -241,7 +241,7 @@ func TestDereferencing(t *testing.T) { 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: types.NewResolutionDidDocMetadata(validMetadata, []*resource.ResourceHeader{validResource.Header}), + expectedMetadata: types.NewResolutionDidDocMetadata(validDid, validMetadata, []*resource.ResourceHeader{validResource.Header}), expectedError: "", }, { @@ -268,7 +268,7 @@ func TestDereferencing(t *testing.T) { name: "successful Primary dereferencing (resource)", ledgerService: NewMockLedgerService(validDIDDoc, validMetadata, validResource), dereferencingType: types.DIDJSONLD, - didUrl: validDid + "/resources/" + validResourceId, + didUrl: validDid + types.RESOURCE_PATH + 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: types.ResolutionDidDocMetadata{}, @@ -310,7 +310,7 @@ func TestDereferencing(t *testing.T) { name: "resource not found", ledgerService: NewMockLedgerService(cheqd.Did{}, cheqd.Metadata{}, resource.Resource{}), dereferencingType: types.DIDJSONLD, - didUrl: validDid + "/resources/00000000-0000-0000-0000-000000000000", + didUrl: validDid + types.RESOURCE_PATH + "00000000-0000-0000-0000-000000000000", expectedMetadata: types.ResolutionDidDocMetadata{}, expectedError: types.DereferencingNotFound, }, diff --git a/types/constants.go b/types/constants.go index 535ef2a1..db344280 100644 --- a/types/constants.go +++ b/types/constants.go @@ -26,3 +26,7 @@ const ( const ( DIDSchemaJSONLD = "https://www.w3.org/ns/did/v1" ) + +const ( + RESOURCE_PATH = "/resources/" +) diff --git a/types/did_doc_metadata.go b/types/did_doc_metadata.go index 58681714..48e891d3 100644 --- a/types/did_doc_metadata.go +++ b/types/did_doc_metadata.go @@ -14,14 +14,14 @@ type ResolutionDidDocMetadata struct { } type ResourcePreview struct { - Id string `json:"id,omitempty"` + ResourceURI string `json:"resourceURI,omitempty"` Name string `json:"name,omitempty"` ResourceType string `json:"resourceType,omitempty"` MediaType string `json:"mediaType,omitempty"` Created string `json:"created,omitempty"` } -func NewResolutionDidDocMetadata(metadata cheqd.Metadata, resources []*resource.ResourceHeader) ResolutionDidDocMetadata { +func NewResolutionDidDocMetadata(did string, metadata cheqd.Metadata, resources []*resource.ResourceHeader) ResolutionDidDocMetadata { newMetadata := ResolutionDidDocMetadata{ metadata.Created, metadata.Updated, @@ -34,7 +34,7 @@ func NewResolutionDidDocMetadata(metadata cheqd.Metadata, resources []*resource. } for _, r := range resources { resourcePreview := ResourcePreview{ - r.Id, + did + RESOURCE_PATH + r.Id, r.Name, r.ResourceType, r.MediaType,