1
1
"""Credential offer message handler."""
2
+ import json
2
3
3
4
from aries_cloudagent .messaging .base_handler import (
4
5
BaseHandler ,
7
8
RequestContext ,
8
9
)
9
10
11
+ from aries_cloudagent .wallet .base import BaseWallet
12
+ from aries_cloudagent .wallet .indy import IndyWallet
13
+
10
14
from ..manager import CredentialManager
11
15
from ..messages .credential_offer import CredentialOffer
16
+ from ..models .credential_exchange import V10CredentialExchange
17
+
18
+ from .....v1_0 .manager import ADAManager , ADAManagerError
19
+ from .....v1_0 .messages .data_agreement_offer import DataAgreementNegotiationOfferMessage
20
+ from .....v1_0 .models .diddoc_model import MyDataDIDResponseBody
21
+ from .....v1_0 .utils .jsonld .data_agreement import verify_data_agreement
22
+ from .....v1_0 .utils .did .mydata_did import DIDMyData
23
+ from .....v1_0 .decorators .data_agreement_context_decorator import DataAgreementContextDecorator
24
+ from .....v1_0 .messages .problem_report import DataAgreementNegotiationProblemReportReason
12
25
13
26
from aries_cloudagent .utils .tracing import trace_event , get_timer
14
27
@@ -27,20 +40,126 @@ async def handle(self, context: RequestContext, responder: BaseResponder):
27
40
"""
28
41
r_time = get_timer ()
29
42
30
- self ._logger .debug ("CredentialOfferHandler called with context %s" , context )
43
+ self ._logger .debug (
44
+ "CredentialOfferHandler called with context %s" , context )
31
45
assert isinstance (context .message , CredentialOffer )
32
46
self ._logger .info (
33
47
"Received credential offer message: %s" ,
34
48
context .message .serialize (as_string = True ),
35
49
)
36
50
37
51
if not context .connection_ready :
38
- raise HandlerException ("No connection established for credential offer" )
52
+ raise HandlerException (
53
+ "No connection established for credential offer" )
39
54
40
55
credential_manager = CredentialManager (context )
41
56
42
57
cred_ex_record = await credential_manager .receive_offer ()
43
58
59
+ # Wallet instance from request context
60
+ wallet : IndyWallet = await context .inject (BaseWallet )
61
+
62
+ # Initialise ADA manager
63
+ ada_manager = ADAManager (context )
64
+
65
+ # Process data agreement context decorator
66
+ data_agreement_context_message = None
67
+ try :
68
+ data_agreement_context_message : DataAgreementNegotiationOfferMessage = await ada_manager .process_data_agreement_context_decorator (
69
+ decorator_set = context .message ._decorators
70
+ )
71
+
72
+ if isinstance (data_agreement_context_message , DataAgreementNegotiationOfferMessage ):
73
+
74
+ # Resolve controller DID (Organisation DID) from MyData DID registry
75
+ controller_mydata_did = DIDMyData .from_did (
76
+ data_agreement_context_message .body .proof .verification_method )
77
+
78
+ await ada_manager .resolve_remote_mydata_did (mydata_did = controller_mydata_did .did )
79
+
80
+ # Verify signatures on data agreement offer
81
+ valid = await verify_data_agreement (
82
+ data_agreement_context_message .body .serialize (),
83
+ controller_mydata_did .public_key_b58 ,
84
+ wallet
85
+ )
86
+
87
+ if not valid :
88
+ self ._logger .error (
89
+ "Data agreement offer verification failed"
90
+ )
91
+
92
+ # Send problem report
93
+ problem_report = await ada_manager .construct_data_agreement_negotiation_problem_report_message (
94
+ connection_record = context .connection_record ,
95
+ data_agreement_id = data_agreement_context_message .body .data_agreement_id ,
96
+ problem_code = DataAgreementNegotiationProblemReportReason .SIGNATURE_VERIFICATION_FAILED .value ,
97
+ explain = "Data agreement offer verification failed"
98
+ )
99
+
100
+ await ada_manager .send_data_agreement_negotiation_problem_report_message (
101
+ connection_record = context .connection_record ,
102
+ data_agreement_negotiation_problem_report_message = problem_report
103
+ )
104
+
105
+ cred_ex_record .data_agreement_status = V10CredentialExchange .DATA_AGREEMENT_PROBLEM_REPORT
106
+ cred_ex_record .data_agreement_problem_report = problem_report .serialize ()
107
+ await cred_ex_record .save (context )
108
+
109
+ raise HandlerException (
110
+ "Data agreement offer signature verification failed"
111
+ )
112
+
113
+ # Update credential exchange record with data agreement
114
+ cred_ex_record .data_agreement = data_agreement_context_message .body .serialize ()
115
+ cred_ex_record .data_agreement_id = data_agreement_context_message .body .data_agreement_id
116
+ cred_ex_record .data_agreement_template_id = data_agreement_context_message .body .data_agreement_template_id
117
+ cred_ex_record .data_agreement_status = V10CredentialExchange .DATA_AGREEMENT_OFFER
118
+
119
+ await cred_ex_record .save (context )
120
+
121
+ # Save data agreement instance metadata
122
+ await ada_manager .store_data_agreement_instance_metadata (
123
+ data_agreement_id = data_agreement_context_message .body .data_agreement_id ,
124
+ data_agreement_template_id = data_agreement_context_message .body .data_agreement_template_id ,
125
+ data_exchange_record_id = cred_ex_record .credential_exchange_id ,
126
+ method_of_use = data_agreement_context_message .body .method_of_use
127
+ )
128
+
129
+ self ._logger .info (
130
+ f"Data agreement offer verified and stored for credential exchange record { cred_ex_record .credential_exchange_id } "
131
+ )
132
+
133
+ self ._logger .info (
134
+ f"Received data agreement offer context message: \n { json .dumps (data_agreement_context_message .serialize (), indent = 4 )} \n "
135
+ )
136
+
137
+ except ADAManagerError as err :
138
+ self ._logger .error (
139
+ "Failed to process data agreement context decorator: %s" , err
140
+ )
141
+
142
+ # Send problem report
143
+ problem_report = await ada_manager .construct_data_agreement_negotiation_problem_report_message (
144
+ connection_record = context .connection_record ,
145
+ data_agreement_id = data_agreement_context_message .body .data_agreement_id ,
146
+ problem_code = None ,
147
+ explain = str (err )
148
+ )
149
+
150
+ await ada_manager .send_data_agreement_negotiation_problem_report_message (
151
+ connection_record = context .connection_record ,
152
+ data_agreement_negotiation_problem_report_message = problem_report
153
+ )
154
+
155
+ cred_ex_record .data_agreement_status = V10CredentialExchange .DATA_AGREEMENT_PROBLEM_REPORT
156
+ cred_ex_record .data_agreement_problem_report = problem_report .serialize ()
157
+ await cred_ex_record .save (context )
158
+
159
+ raise HandlerException (
160
+ "Failed to process data agreement context decorator: %s" % err
161
+ )
162
+
44
163
r_time = trace_event (
45
164
context .settings ,
46
165
context .message ,
@@ -54,6 +173,43 @@ async def handle(self, context: RequestContext, responder: BaseResponder):
54
173
cred_ex_record = cred_ex_record ,
55
174
holder_did = context .connection_record .my_did ,
56
175
)
176
+
177
+ if data_agreement_context_message :
178
+ try :
179
+ (data_agreement_instance , data_agreement_negotiation_accept_message ) = await ada_manager .construct_data_agreement_negotiation_accept_message (
180
+ data_agreement_negotiation_offer_body = data_agreement_context_message .body ,
181
+ connection_record = context .connection_record ,
182
+ )
183
+
184
+ # Update credential request message with data agreement context decorator
185
+ credential_request_message ._decorators ["data-agreement-context" ] = DataAgreementContextDecorator (
186
+ message_type = "protocol" ,
187
+ message = data_agreement_negotiation_accept_message .serialize ()
188
+ )
189
+
190
+ # Update credential exchange record with data agreement
191
+ cred_ex_record .data_agreement = data_agreement_instance .serialize ()
192
+ cred_ex_record .data_agreement_status = V10CredentialExchange .DATA_AGREEMENT_ACCEPT
193
+
194
+ await cred_ex_record .save (context )
195
+
196
+ self ._logger .info (
197
+ f"Data agreement offer accepted and stored for credential exchange record { cred_ex_record .credential_exchange_id } "
198
+ )
199
+
200
+ self ._logger .info (
201
+ f"Data agreement negotiation accept context message: \n { json .dumps (data_agreement_negotiation_accept_message .serialize (), indent = 4 )} \n "
202
+ )
203
+
204
+ except ADAManagerError as err :
205
+ self ._logger .error (
206
+ "Failed to construct data agreement negotiation accept message: %s" , err
207
+ )
208
+
209
+ raise HandlerException (
210
+ "Failed to construct data agreement negotiation accept message: %s" % err
211
+ )
212
+
57
213
await responder .send_reply (credential_request_message )
58
214
59
215
trace_event (
0 commit comments