Skip to content

Commit 7ea4014

Browse files
authored
Merge pull request #243 from andrewwhitehead/perf-issue-credential
Use issue-credential protocol in performance demo
2 parents 34c7783 + 76df197 commit 7ea4014

File tree

6 files changed

+124
-103
lines changed

6 files changed

+124
-103
lines changed

aries_cloudagent/messaging/issue_credential/v1_0/manager.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def context(self) -> InjectionContext:
4949

5050
async def prepare_send(
5151
self, connection_id: str, credential_proposal: CredentialProposal
52-
) -> V10CredentialExchange:
52+
) -> Tuple[V10CredentialExchange, CredentialOffer]:
5353
"""
5454
Set up a new credential exchange for an automated send.
5555
@@ -59,7 +59,7 @@ async def prepare_send(
5959
attribute values to use if auto_issue is enabled
6060
6161
Returns:
62-
A new credential exchange record
62+
A tuple of the new credential exchange record and credential offer message
6363
6464
"""
6565

@@ -77,11 +77,11 @@ async def prepare_send(
7777
credential_definition_id=credential_definition_id,
7878
credential_proposal_dict=credential_proposal.serialize(),
7979
)
80-
(credential_exchange, _) = await self.create_offer(
80+
(credential_exchange, credential_offer) = await self.create_offer(
8181
credential_exchange_record=credential_exchange,
8282
comment="create automated credential exchange",
8383
)
84-
return credential_exchange
84+
return credential_exchange, credential_offer
8585

8686
async def create_proposal(
8787
self,

aries_cloudagent/messaging/issue_credential/v1_0/routes.py

Lines changed: 39 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
from .manager import CredentialManager
1515
from .messages.credential_proposal import CredentialProposal
1616
from .messages.inner.credential_preview import (
17-
CredAttrSpec,
1817
CredentialPreview,
1918
CredentialPreviewSchema,
2019
)
@@ -51,7 +50,7 @@ class V10CredentialProposalRequestSchema(Schema):
5150
**INDY_CRED_DEF_ID,
5251
)
5352
comment = fields.Str(description="Human-readable comment", required=False)
54-
credential_proposal = fields.Nested(CredentialPreviewSchema, required=True)
53+
credential_preview = fields.Nested(CredentialPreviewSchema, required=True)
5554

5655

5756
class V10CredentialOfferRequestSchema(Schema):
@@ -190,27 +189,12 @@ async def credential_exchange_send(request: web.BaseRequest):
190189
connection_id = body.get("connection_id")
191190
credential_definition_id = body.get("credential_definition_id")
192191
comment = body.get("comment")
193-
credential_proposal = CredentialProposal(
194-
comment=comment,
195-
credential_proposal=CredentialPreview(
196-
attributes=[
197-
CredAttrSpec(
198-
name=attr_preview["name"],
199-
mime_type=attr_preview.get("mime-type", None),
200-
value=attr_preview["value"],
201-
)
202-
for attr_preview in body.get("credential_proposal")["attributes"]
203-
]
204-
),
205-
cred_def_id=credential_definition_id,
206-
)
192+
preview_spec = body.get("credential_preview")
207193

208-
if not credential_proposal:
209-
raise web.HTTPBadRequest(
210-
reason="credential_proposal must be provided with attribute values."
211-
)
212-
213-
credential_manager = CredentialManager(context)
194+
if not credential_definition_id:
195+
raise web.HTTPBadRequest(reason="credential_definition_id must be provided.")
196+
if not preview_spec:
197+
raise web.HTTPBadRequest(reason="credential_preview must be provided.")
214198

215199
try:
216200
connection_record = await ConnectionRecord.retrieve_by_id(
@@ -222,18 +206,19 @@ async def credential_exchange_send(request: web.BaseRequest):
222206
if not connection_record.is_ready:
223207
raise web.HTTPForbidden()
224208

225-
credential_exchange_record = await credential_manager.prepare_send(
226-
connection_id, credential_proposal=credential_proposal
209+
credential_proposal = CredentialProposal(
210+
comment=comment,
211+
credential_proposal=CredentialPreview.deserialize(preview_spec),
212+
cred_def_id=credential_definition_id,
227213
)
228214

215+
credential_manager = CredentialManager(context)
216+
229217
(
230218
credential_exchange_record,
231219
credential_offer_message,
232-
) = await credential_manager.create_offer(
233-
credential_exchange_record,
234-
comment="Automated offer creation on cred def id "
235-
f"{credential_exchange_record.credential_definition_id}, "
236-
f"parent thread {credential_exchange_record.parent_thread_id}",
220+
) = await credential_manager.prepare_send(
221+
connection_id, credential_proposal=credential_proposal
237222
)
238223
await outbound_handler(
239224
credential_offer_message, connection_id=credential_exchange_record.connection_id
@@ -264,14 +249,10 @@ async def credential_exchange_send_proposal(request: web.BaseRequest):
264249
connection_id = body.get("connection_id")
265250
credential_definition_id = body.get("credential_definition_id")
266251
comment = body.get("comment")
267-
proposal_spec = body.get("credential_proposal")
268-
269-
if not proposal_spec:
270-
raise web.HTTPBadRequest(reason="credential_proposal must be provided.")
271-
272-
credential_preview = CredentialPreview.deserialize(proposal_spec)
252+
preview_spec = body.get("credential_preview")
273253

274-
credential_manager = CredentialManager(context)
254+
if not preview_spec:
255+
raise web.HTTPBadRequest(reason="credential_preview must be provided.")
275256

276257
try:
277258
connection_record = await ConnectionRecord.retrieve_by_id(
@@ -283,6 +264,10 @@ async def credential_exchange_send_proposal(request: web.BaseRequest):
283264
if not connection_record.is_ready:
284265
raise web.HTTPForbidden()
285266

267+
credential_preview = CredentialPreview.deserialize(preview_spec)
268+
269+
credential_manager = CredentialManager(context)
270+
286271
credential_exchange_record = await credential_manager.create_proposal(
287272
connection_id,
288273
comment=comment,
@@ -332,19 +317,17 @@ async def credential_exchange_send_free_offer(request: web.BaseRequest):
332317
"auto_issue", context.settings.get("debug.auto_respond_credential_request")
333318
)
334319
comment = body.get("comment")
335-
proposal_spec = body.get("credential_proposal")
320+
preview_spec = body.get("credential_preview")
336321

337322
if not credential_definition_id:
338323
raise web.HTTPBadRequest(reason="credential_definition_id is required")
339324

340-
if auto_issue and not proposal_spec:
325+
if auto_issue and not preview_spec:
341326
raise web.HTTPBadRequest(
342327
reason="If auto_issue is set to"
343328
+ " true then credential_preview must also be provided."
344329
)
345330

346-
credential_manager = CredentialManager(context)
347-
348331
try:
349332
connection_record = await ConnectionRecord.retrieve_by_id(
350333
context, connection_id
@@ -355,8 +338,8 @@ async def credential_exchange_send_free_offer(request: web.BaseRequest):
355338
if not connection_record.is_ready:
356339
raise web.HTTPForbidden()
357340

358-
if proposal_spec:
359-
credential_preview = CredentialPreview.deserialize(proposal_spec)
341+
if preview_spec:
342+
credential_preview = CredentialPreview.deserialize(preview_spec)
360343
credential_proposal = CredentialProposal(
361344
comment=comment,
362345
credential_proposal=credential_preview,
@@ -374,6 +357,8 @@ async def credential_exchange_send_free_offer(request: web.BaseRequest):
374357
auto_issue=auto_issue,
375358
)
376359

360+
credential_manager = CredentialManager(context)
361+
377362
(
378363
credential_exchange_record,
379364
credential_offer_message,
@@ -466,8 +451,6 @@ async def credential_exchange_send_request(request: web.BaseRequest):
466451
V10CredentialExchange.STATE_OFFER_RECEIVED
467452
)
468453

469-
credential_manager = CredentialManager(context)
470-
471454
try:
472455
connection_record = await ConnectionRecord.retrieve_by_id(
473456
context, connection_id
@@ -478,6 +461,8 @@ async def credential_exchange_send_request(request: web.BaseRequest):
478461
if not connection_record.is_ready:
479462
raise web.HTTPForbidden()
480463

464+
credential_manager = CredentialManager(context)
465+
481466
(
482467
credential_exchange_record,
483468
credential_request_message,
@@ -508,7 +493,10 @@ async def credential_exchange_issue(request: web.BaseRequest):
508493

509494
body = await request.json()
510495
comment = body.get("comment")
511-
credential_preview = CredentialPreview.deserialize(body["credential_preview"])
496+
preview_spec = body.get("credential_preview")
497+
498+
if not preview_spec:
499+
raise web.HTTPBadRequest(reason="credential_preview must be provided.")
512500

513501
credential_exchange_id = request.match_info["cred_ex_id"]
514502
cred_exch_record = await V10CredentialExchange.retrieve_by_id(
@@ -518,8 +506,6 @@ async def credential_exchange_issue(request: web.BaseRequest):
518506

519507
assert cred_exch_record.state == V10CredentialExchange.STATE_REQUEST_RECEIVED
520508

521-
credential_manager = CredentialManager(context)
522-
523509
try:
524510
connection_record = await ConnectionRecord.retrieve_by_id(
525511
context, connection_id
@@ -530,6 +516,10 @@ async def credential_exchange_issue(request: web.BaseRequest):
530516
if not connection_record.is_ready:
531517
raise web.HTTPForbidden()
532518

519+
credential_preview = CredentialPreview.deserialize(preview_spec)
520+
521+
credential_manager = CredentialManager(context)
522+
533523
(
534524
cred_exch_record,
535525
credential_issue_message,
@@ -569,8 +559,6 @@ async def credential_exchange_store(request: web.BaseRequest):
569559
V10CredentialExchange.STATE_CREDENTIAL_RECEIVED
570560
)
571561

572-
credential_manager = CredentialManager(context)
573-
574562
try:
575563
connection_record = await ConnectionRecord.retrieve_by_id(
576564
context, connection_id
@@ -581,6 +569,8 @@ async def credential_exchange_store(request: web.BaseRequest):
581569
if not connection_record.is_ready:
582570
raise web.HTTPForbidden()
583571

572+
credential_manager = CredentialManager(context)
573+
584574
(
585575
credential_exchange_record,
586576
credential_stored_message,

aries_cloudagent/messaging/issue_credential/v1_0/tests/test_manager.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,11 @@ async def test_prepare_send(self):
4141
with async_mock.patch.object(
4242
self.manager, "create_offer", autospec=True
4343
) as create_offer:
44-
create_offer.return_value = (object(), None)
45-
ret_exchange = await self.manager.prepare_send(connection_id, proposal)
44+
create_offer.return_value = (async_mock.MagicMock(), async_mock.MagicMock())
45+
ret_exchange, ret_cred_offer = await self.manager.prepare_send(connection_id, proposal)
4646
create_offer.assert_called_once()
4747
assert ret_exchange is create_offer.return_value[0]
48-
exchange: V10CredentialExchange = create_offer.call_args[1][
49-
"credential_exchange_record"
50-
]
48+
exchange = create_offer.call_args[1]["credential_exchange_record"]
5149
assert exchange.auto_issue
5250
assert exchange.connection_id == connection_id
5351
assert exchange.credential_definition_id == cred_def_id

aries_cloudagent/messaging/issue_credential/v1_0/tests/test_routes.py

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ async def test_credential_exchange_send(self):
2121
test_module, "ConnectionRecord", autospec=True
2222
) as mock_connection_record, async_mock.patch.object(
2323
test_module, "CredentialManager", autospec=True
24-
) as mock_credential_manager:
24+
) as mock_credential_manager, async_mock.patch.object(
25+
test_module.CredentialPreview, "deserialize", autospec=True
26+
):
2527
test_module.web.json_response = async_mock.CoroutineMock()
2628

2729
mock_credential_manager.return_value.create_offer = (
@@ -34,17 +36,16 @@ async def test_credential_exchange_send(self):
3436
)
3537

3638
mock_cred_ex_record = async_mock.MagicMock()
39+
mock_cred_offer = async_mock.MagicMock()
3740

3841
mock_credential_manager.return_value.prepare_send.return_value = (
39-
mock_cred_ex_record
42+
(mock_cred_ex_record, mock_cred_offer)
4043
)
4144

4245
await test_module.credential_exchange_send(mock)
4346

4447
test_module.web.json_response.assert_called_once_with(
45-
mock_credential_manager.return_value.create_offer.return_value[
46-
0
47-
].serialize.return_value
48+
mock_cred_ex_record.serialize.return_value
4849
)
4950

5051
async def test_credential_exchange_send_no_conn_record(self):
@@ -65,13 +66,8 @@ async def test_credential_exchange_send_no_conn_record(self):
6566
test_module.web.json_response = async_mock.CoroutineMock()
6667

6768
# Emulate storage not found (bad connection id)
68-
mock_connection_record.retrieve_by_id = async_mock.CoroutineMock(
69-
side_effect=StorageNotFoundError
70-
)
69+
mock_connection_record.retrieve_by_id.side_effect = StorageNotFoundError
7170

72-
mock_credential_manager.return_value.create_offer = (
73-
async_mock.CoroutineMock()
74-
)
7571
mock_credential_manager.return_value.create_offer.return_value = (
7672
async_mock.MagicMock(),
7773
async_mock.MagicMock(),
@@ -98,12 +94,8 @@ async def test_credential_exchange_send_not_ready(self):
9894
test_module.web.json_response = async_mock.CoroutineMock()
9995

10096
# Emulate connection not ready
101-
mock_connection_record.retrieve_by_id = async_mock.CoroutineMock()
10297
mock_connection_record.retrieve_by_id.return_value.is_ready = False
10398

104-
mock_credential_manager.return_value.create_offer = (
105-
async_mock.CoroutineMock()
106-
)
10799
mock_credential_manager.return_value.create_offer.return_value = (
108100
async_mock.MagicMock(),
109101
async_mock.MagicMock(),
@@ -114,14 +106,11 @@ async def test_credential_exchange_send_not_ready(self):
114106

115107
async def test_credential_exchange_send_proposal(self):
116108
conn_id = "connection-id"
117-
proposal_spec = {"attributes": [{"name": "attr", "value": "value"}]}
109+
preview_spec = {"attributes": [{"name": "attr", "value": "value"}]}
118110

119111
mock = async_mock.MagicMock()
120112
mock.json = async_mock.CoroutineMock(
121-
return_value={
122-
"connection_id": conn_id,
123-
"credential_proposal": proposal_spec,
124-
}
113+
return_value={"connection_id": conn_id, "credential_preview": preview_spec}
125114
)
126115
mock.app = {
127116
"outbound_message_router": async_mock.CoroutineMock(),
@@ -218,7 +207,10 @@ async def test_credential_exchange_send_proposal_not_ready(self):
218207
async def test_credential_exchange_send_free_offer(self):
219208
mock = async_mock.MagicMock()
220209
mock.json = async_mock.CoroutineMock(
221-
return_value={"auto_issue": False, "credential_definition_id": "cred-def-id"}
210+
return_value={
211+
"auto_issue": False,
212+
"credential_definition_id": "cred-def-id",
213+
}
222214
)
223215

224216
mock.app = {
@@ -257,7 +249,10 @@ async def test_credential_exchange_send_free_offer(self):
257249
async def test_credential_exchange_send_free_offer_no_conn_record(self):
258250
mock = async_mock.MagicMock()
259251
mock.json = async_mock.CoroutineMock(
260-
return_value={"auto_issue": False, "credential_definition_id": "cred-def-id"}
252+
return_value={
253+
"auto_issue": False,
254+
"credential_definition_id": "cred-def-id",
255+
}
261256
)
262257

263258
mock.app = {

0 commit comments

Comments
 (0)