Skip to content

Commit 36e4c79

Browse files
committed
feat: Use acceptheaders in cheqdResolver for dereferencing
Signed-off-by: DaevMithran <[email protected]>
1 parent 80e09c3 commit 36e4c79

File tree

2 files changed

+59
-65
lines changed

2 files changed

+59
-65
lines changed

cheqd/cheqd/anoncreds/registry.py

+8-11
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ async def get_schema_info_by_schema_id(
133133

134134
async def get_schema(self, _profile: Profile, schema_id: str) -> GetSchemaResult:
135135
"""Get a schema from the registry."""
136-
resource_with_metadata = await self.resolver.resolve_resource(schema_id)
136+
resource_with_metadata = await self.resolver.dereference_with_metadata(_profile, schema_id)
137137
schema = resource_with_metadata.resource
138138
metadata = resource_with_metadata.metadata
139139

@@ -168,7 +168,8 @@ async def register_schema(
168168
try:
169169
# check if schema already exists
170170
try:
171-
existing_schema = await self.resolver.resolve_resource(
171+
existing_schema = await self.resolver.dereference_with_metadata(
172+
profile,
172173
f"{schema.issuer_id}?resourceName={resource_name}&resourceType={resource_type}"
173174
)
174175
except DIDNotFound:
@@ -179,7 +180,6 @@ async def register_schema(
179180
LOGGER.debug("Existing schema %s", existing_schema)
180181
# update if schema exists
181182
if existing_schema is not None:
182-
LOGGER.debug("UPDATING SCHEMA")
183183
cheqd_schema = ResourceUpdateRequestOptions(
184184
options=Options(
185185
name=resource_name,
@@ -255,9 +255,7 @@ async def get_credential_definition(
255255
self, _profile: Profile, credential_definition_id: str
256256
) -> GetCredDefResult:
257257
"""Get a credential definition from the registry."""
258-
resource_with_metadata = await self.resolver.resolve_resource(
259-
credential_definition_id
260-
)
258+
resource_with_metadata = await self.resolver.dereference_with_metadata(_profile, credential_definition_id)
261259
credential_definition = resource_with_metadata.resource
262260
metadata = resource_with_metadata.metadata
263261
(did, resource_id) = self.split_did_url(credential_definition_id)
@@ -334,9 +332,7 @@ async def get_revocation_registry_definition(
334332
self, _profile: Profile, revocation_registry_id: str
335333
) -> GetRevRegDefResult:
336334
"""Get a revocation registry definition from the registry."""
337-
resource_with_metadata = await self.resolver.resolve_resource(
338-
revocation_registry_id
339-
)
335+
resource_with_metadata = await self.resolver.dereference_with_metadata(_profile, revocation_registry_id)
340336
revocation_registry_definition = resource_with_metadata.resource
341337
metadata = resource_with_metadata.metadata
342338

@@ -436,7 +432,8 @@ async def get_revocation_list(
436432
dt_object = datetime.fromtimestamp(epoch_time, tz=timezone.utc)
437433

438434
resource_time = dt_object.strftime("%Y-%m-%dT%H:%M:%SZ")
439-
resource_with_metadata = await self.resolver.resolve_resource(
435+
resource_with_metadata = await self.resolver.dereference_with_metadata(
436+
profile,
440437
f"{did}?resourceType={resource_type}&resourceName={resource_name}&resourceVersionTime={resource_time}"
441438
)
442439
status_list = resource_with_metadata.resource
@@ -460,7 +457,7 @@ async def get_schema_info_by_id(
460457
self, profile: Profile, schema_id: str
461458
) -> AnoncredsSchemaInfo:
462459
"""Get a schema info from the registry."""
463-
resource_with_metadata = await self.resolver.resolve_resource(schema_id)
460+
resource_with_metadata = await self.resolver.dereference_with_metadata(profile, schema_id)
464461
schema = resource_with_metadata.resource
465462
(did, resource_id) = self.split_did_url(schema_id)
466463
anoncreds_schema = AnoncredsSchemaInfo(

cheqd/cheqd/resolver/resolver.py

+51-54
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,31 @@
1414
)
1515
from aiohttp import ClientSession
1616
from pydid import DIDDocument
17+
from pydantic import BaseModel
1718

1819
from ..validation import CheqdDID
1920

20-
2121
@dataclass
2222
class DIDLinkedResourceWithMetadata:
2323
"""Schema for DID Linked Resource with metadata."""
2424

2525
resource: dict
2626
metadata: dict
2727

28+
class DIDUrlDereferencingResult(BaseModel):
29+
"""DID Url Dereferencing Result with Metadata."""
30+
31+
contentStream: dict
32+
contentMetadata: dict
33+
34+
class Config:
35+
"""Pydantic config."""
36+
37+
extra = "allow"
38+
39+
DID_RESOLUTION_HEADER = "application/ld+json;profile=https://w3id.org/did-resolution"
40+
DID_URL_DEREFERENCING_HEADER = "application/ld+json;profile=https://w3id.org/did-url-dereferencing"
41+
2842

2943
class CheqdDIDResolver(BaseDIDResolver):
3044
"""DID Resolver implementation for did:cheqd."""
@@ -52,26 +66,19 @@ async def _resolve(
5266
service_accept: Optional[Sequence[Text]] = None,
5367
) -> dict:
5468
"""Resolve a Cheqd DID."""
69+
headers = {}
70+
if service_accept:
71+
# Convert the Sequence[Text] to a dictionary for headers
72+
headers = dict(item.split(": ", 1) for item in service_accept)
5573
async with ClientSession() as session:
5674
async with session.get(
5775
self.DID_RESOLVER_BASE_URL + did,
76+
headers=headers,
5877
) as response:
5978
if response.status == 200:
6079
try:
61-
# Validate DIDDoc with pyDID
6280
resolver_resp = await response.json()
63-
did_doc_resp = resolver_resp.get("didDocument")
64-
did_doc_metadata = resolver_resp.get("didDocumentMetadata")
65-
66-
did_doc = DIDDocument.from_json(json.dumps(did_doc_resp))
67-
result = did_doc.serialize()
68-
# Check if 'deactivated' field is present in didDocumentMetadata
69-
if (
70-
did_doc_metadata
71-
and did_doc_metadata.get("deactivated") is True
72-
):
73-
result["deactivated"] = True
74-
return result
81+
return resolver_resp
7582
except Exception as err:
7683
raise ResolverError("Response was incorrectly formatted") from err
7784
if response.status == 404:
@@ -80,44 +87,34 @@ async def _resolve(
8087
"Could not find doc for {}: {}".format(did, await response.text())
8188
)
8289

83-
async def resolve_resource(self, did: str) -> DIDLinkedResourceWithMetadata:
90+
async def resolve(
91+
self,
92+
profile: Profile,
93+
did: str,
94+
service_accept: Optional[Sequence[Text]] = None,
95+
) -> dict:
96+
resolver_resp = await self._resolve(profile, did, service_accept)
97+
98+
did_doc_resp = resolver_resp.get("didDocument")
99+
did_doc_metadata = resolver_resp.get("didDocumentMetadata")
100+
101+
did_doc = DIDDocument.from_json(json.dumps(did_doc_resp))
102+
result = did_doc.serialize()
103+
# Check if 'deactivated' field is present in didDocumentMetadata
104+
if (
105+
did_doc_metadata
106+
and did_doc_metadata.get("deactivated") is True
107+
):
108+
result["deactivated"] = True
109+
return result
110+
111+
async def dereference_with_metadata(self, profile: Profile, did_url: str) -> DIDLinkedResourceWithMetadata:
84112
"""Resolve a Cheqd DID Linked Resource and its Metadata."""
85-
async with ClientSession() as session:
86-
# Fetch the main resource
87-
async with session.get(self.DID_RESOLVER_BASE_URL + did) as response:
88-
if response.status == 200:
89-
try:
90-
resource = await response.json()
91-
except Exception as err:
92-
raise ResolverError("Response was incorrectly formatted") from err
93-
elif response.status == 404:
94-
raise DIDNotFound(f"No resource found for {did}")
95-
else:
96-
raise ResolverError(
97-
f"Could not find resource for {did}: {await response.text()}"
98-
)
99-
100-
# Fetch the metadata
101-
async with session.get(
102-
f"{self.DID_RESOLVER_BASE_URL}{did}&resourceMetadata=true"
103-
if "resourceName" in did
104-
else f"{self.DID_RESOLVER_BASE_URL}{did}/metadata"
105-
) as response:
106-
if response.status == 200:
107-
try:
108-
result = await response.json()
109-
metadata = result.get("contentStream").get(
110-
"linkedResourceMetadata"
111-
)[0]
112-
except Exception as err:
113-
raise ResolverError(
114-
"Metadata response was incorrectly formatted"
115-
) from err
116-
elif response.status == 404:
117-
raise DIDNotFound(f"No metadata found for {did}")
118-
else:
119-
raise ResolverError(
120-
f"Could not find metadata for {did}: {await response.text()}"
121-
)
122-
123-
return DIDLinkedResourceWithMetadata(resource=resource, metadata=metadata)
113+
# Fetch the main resource
114+
result = await self._resolve(profile, did_url, [f"Accept: {DID_URL_DEREFERENCING_HEADER}"])
115+
116+
validated_resp = DIDUrlDereferencingResult(**result)
117+
return DIDLinkedResourceWithMetadata(
118+
resource=validated_resp.contentStream,
119+
metadata=validated_resp.contentMetadata
120+
)

0 commit comments

Comments
 (0)