|
33 | 33 | from aries_cloudagent.wallet.error import WalletError
|
34 | 34 | from aries_cloudagent.utils.outofband import serialize_outofband
|
35 | 35 | from aries_cloudagent.utils.tracing import trace_event, get_timer, AdminAPIMessageTracingSchema
|
| 36 | +from aries_cloudagent.wallet.indy import IndyWallet |
| 37 | +from aries_cloudagent.wallet.base import BaseWallet |
36 | 38 |
|
37 | 39 | from aries_cloudagent.protocols.problem_report.v1_0 import internal_error
|
38 | 40 | from aries_cloudagent.protocols.problem_report.v1_0.message import ProblemReport
|
|
57 | 59 | from ....v1_0.models.data_agreement_negotiation_offer_model import DataAgreementNegotiationOfferBody, DataAgreementNegotiationOfferBodySchema
|
58 | 60 | from ....v1_0.manager import ADAManager, ADAManagerError
|
59 | 61 | from ....v1_0.models.data_agreement_negotiation_offer_model import DataAgreementNegotiationOfferBody, DataAgreementNegotiationOfferBodySchema
|
60 |
| - |
| 62 | +from ....v1_0.models.data_agreement_instance_model import DataAgreementInstance, DataAgreementInstanceSchema |
| 63 | +from ....v1_0.utils.did.mydata_did import DIDMyData |
| 64 | +from ....v1_0.utils.wallet.key_type import KeyType |
61 | 65 |
|
62 | 66 | class V10CredentialExchangeListQueryStringSchema(OpenAPISchema):
|
63 | 67 | """Parameters and validators for credential exchange list query."""
|
@@ -1613,6 +1617,96 @@ async def send_data_agreement_negotiation_problem_report(request: web.BaseReques
|
1613 | 1617 | return web.json_response({})
|
1614 | 1618 |
|
1615 | 1619 |
|
| 1620 | +@docs( |
| 1621 | + tags=["issue-credential"], summary="Send data agreement termination message." |
| 1622 | +) |
| 1623 | +@match_info_schema(CredExIdMatchInfoSchema()) |
| 1624 | +@response_schema(V10CredentialExchangeSchema(), 200) |
| 1625 | +async def send_data_agreement_termination_message(request: web.BaseRequest): |
| 1626 | + """ |
| 1627 | + Request handler for sending data agreement termination message. |
| 1628 | +
|
| 1629 | + Args: |
| 1630 | + request: aiohttp request object |
| 1631 | +
|
| 1632 | + """ |
| 1633 | + |
| 1634 | + # Initialize request context |
| 1635 | + context = request.app["request_context"] |
| 1636 | + |
| 1637 | + # Initialize outbound handler |
| 1638 | + outbound_handler = request.app["outbound_message_router"] |
| 1639 | + |
| 1640 | + # Path parameters |
| 1641 | + credential_exchange_id = request.match_info["cred_ex_id"] |
| 1642 | + |
| 1643 | + cred_ex_record = None |
| 1644 | + try: |
| 1645 | + # Fetch credential exchange record |
| 1646 | + cred_ex_record: V10CredentialExchange = await V10CredentialExchange.retrieve_by_id( |
| 1647 | + context, credential_exchange_id |
| 1648 | + ) |
| 1649 | + except StorageNotFoundError as err: |
| 1650 | + raise web.HTTPNotFound(reason=err.roll_up) from err |
| 1651 | + |
| 1652 | + if not cred_ex_record.data_agreement: |
| 1653 | + raise web.HTTPBadRequest(reason=f"Data agreement is not available.") |
| 1654 | + |
| 1655 | + if not cred_ex_record.data_agreement_status == V10CredentialExchange.DATA_AGREEMENT_ACCEPT: |
| 1656 | + raise web.HTTPBadRequest( |
| 1657 | + reason=f"Data agreement must be in accept state to terminate it." |
| 1658 | + ) |
| 1659 | + |
| 1660 | + # Send data agreement terminate message |
| 1661 | + |
| 1662 | + data_agreement_instance: DataAgreementInstance = DataAgreementInstanceSchema().load( |
| 1663 | + cred_ex_record.data_agreement |
| 1664 | + ) |
| 1665 | + |
| 1666 | + # Initialize ADA manager |
| 1667 | + ada_manager = ADAManager(context) |
| 1668 | + |
| 1669 | + connection_record = None |
| 1670 | + connection_id = cred_ex_record.connection_id |
| 1671 | + try: |
| 1672 | + connection_record = await ConnectionRecord.retrieve_by_id( |
| 1673 | + context, connection_id |
| 1674 | + ) |
| 1675 | + if not connection_record.is_ready: |
| 1676 | + raise web.HTTPForbidden( |
| 1677 | + reason=f"Connection {connection_id} not ready") |
| 1678 | + |
| 1679 | + # Fetch wallet from context |
| 1680 | + wallet: IndyWallet = await context.inject(BaseWallet) |
| 1681 | + |
| 1682 | + pairwise_local_did_record = await wallet.get_local_did(connection_record.my_did) |
| 1683 | + principle_did = DIDMyData.from_public_key_b58( |
| 1684 | + pairwise_local_did_record.verkey, key_type=KeyType.ED25519) |
| 1685 | + |
| 1686 | + if data_agreement_instance.principle_did != principle_did.did: |
| 1687 | + raise web.HTTPBadRequest( |
| 1688 | + reason=f"Only the principle can terminate the data agreement." |
| 1689 | + ) |
| 1690 | + |
| 1691 | + |
| 1692 | + (data_agreement_instance, data_agreement_terminate_message) = await ada_manager.construct_data_agreement_termination_terminate_message( |
| 1693 | + data_agreement_instance=data_agreement_instance, |
| 1694 | + connection_record=connection_record, |
| 1695 | + ) |
| 1696 | + |
| 1697 | + # Update credential exchange record with data agreement |
| 1698 | + cred_ex_record.data_agreement = data_agreement_instance.serialize() |
| 1699 | + cred_ex_record.data_agreement_status = V10CredentialExchange.DATA_AGREEMENT_TERMINATE |
| 1700 | + |
| 1701 | + await cred_ex_record.save(context) |
| 1702 | + |
| 1703 | + await outbound_handler(data_agreement_terminate_message, connection_id=cred_ex_record.connection_id) |
| 1704 | + |
| 1705 | + except (ADAManagerError,StorageError) as err: |
| 1706 | + raise web.HTTPBadRequest(reason=err.roll_up) from err |
| 1707 | + |
| 1708 | + return web.json_response(cred_ex_record.serialize()) |
| 1709 | + |
1616 | 1710 | async def register(app: web.Application):
|
1617 | 1711 | """Register routes."""
|
1618 | 1712 |
|
@@ -1668,6 +1762,11 @@ async def register(app: web.Application):
|
1668 | 1762 | send_data_agreement_negotiation_problem_report,
|
1669 | 1763 | ),
|
1670 | 1764 |
|
| 1765 | + web.post( |
| 1766 | + "/issue-credential/records/{cred_ex_id}/data-agreement-termination/terminate", |
| 1767 | + send_data_agreement_termination_message, |
| 1768 | + ), |
| 1769 | + |
1671 | 1770 | ]
|
1672 | 1771 | )
|
1673 | 1772 |
|
|
0 commit comments