14
14
)
15
15
from aiohttp import ClientSession
16
16
from pydid import DIDDocument
17
+ from pydantic import BaseModel
17
18
18
19
from ..validation import CheqdDID
19
20
20
-
21
21
@dataclass
22
22
class DIDLinkedResourceWithMetadata :
23
23
"""Schema for DID Linked Resource with metadata."""
24
24
25
25
resource : dict
26
26
metadata : dict
27
27
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
+
28
42
29
43
class CheqdDIDResolver (BaseDIDResolver ):
30
44
"""DID Resolver implementation for did:cheqd."""
@@ -52,26 +66,19 @@ async def _resolve(
52
66
service_accept : Optional [Sequence [Text ]] = None ,
53
67
) -> dict :
54
68
"""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 )
55
73
async with ClientSession () as session :
56
74
async with session .get (
57
75
self .DID_RESOLVER_BASE_URL + did ,
76
+ headers = headers ,
58
77
) as response :
59
78
if response .status == 200 :
60
79
try :
61
- # Validate DIDDoc with pyDID
62
80
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
75
82
except Exception as err :
76
83
raise ResolverError ("Response was incorrectly formatted" ) from err
77
84
if response .status == 404 :
@@ -80,44 +87,34 @@ async def _resolve(
80
87
"Could not find doc for {}: {}" .format (did , await response .text ())
81
88
)
82
89
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 :
84
112
"""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