openwallet-foundation / acapy

ACA-Py is a foundation for building decentralized identity applications and services running in non-mobile environments.
https://aca-py.org
Apache License 2.0
418 stars 511 forks source link

OOB invitation: Model must include non-empty handshake_protocols or requests_attach or both - though in place #2070

Closed pstuermlinger closed 1 year ago

pstuermlinger commented 1 year ago

Using 0.7.5 I try to process an OOB present-proof.

Steps to reproduce: 1) At verifier: POST /present-proof/create-request Body:

{
  "auto_verify": true,
  "proof_request": {
    "name": "my-proof",
    "requested_attributes": {
      "firstName": {
        "name": "firstName",
        "restrictions": [
          {
            "cred_def_id": "my-cred-def-id"
          }
        ]
      }
    },
    "requested_predicates": {},
    "version": "1.0"
  },
  "trace": false
}

2) At verifier: POST /out-of-band/create-invitation Body:

{
  "attachments": [
    {
      "id": "$presentation_exchange_id from above response",
      "type": "present-proof"
    }
  ]
}

3) At holder: POST resulting oob invitation to /out-of-band/receive-invitation Body:

{
  "invitation": {
    "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/out-of-band/1.1/invitation",
    "@id": "6ebcb4d6-628b-44de-99bf-b30e6f54c258",
    "services": [
      {
        "id": "#inline",
        "type": "did-communication",
        "recipientKeys": [
          "did:key:z6MkrWU3yJioLKhXLmt8PTubfSqeoihJpzWntBhmC6DCCDoo"
        ],
        "serviceEndpoint": "http://192.168.56.1:10002"
      }
    ],
    "label": "Verifier",
    "requests~attach": [
      {
        "@id": "request-0",
        "mime-type": "application/json",
        "data": {
          "json": {
            "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/present-proof/1.0/request-presentation",
            "@id": "0ce52b2d-68af-410b-983b-0a0c17a98e27",
            "request_presentations~attach": [
              {
                "@id": "libindy-request-presentation-0",
                "mime-type": "application/json",
                "data": {
                  "base64": "ey...=="
                }
              }
            ],
            "~thread": {
              "pthid": "6ebcb4d6-628b-44de-99bf-b30e6f54c258"
            }
          }
        }
      }
    ]
  },
  "invi_msg_id": "6ebcb4d6-628b-44de-99bf-b30e6f54c258",
  "oob_id": "fe11e3a7-059f-4738-9ee9-d1fd2d91d1a7",
  "state": "initial",
  "trace": false,
  "invitation_url": "http://192.168.56.1:10002?oob=ey...="
}

Result at holder:

2023-01-09 13:39:30,741 aries_cloudagent.admin.server DEBUG Incoming request: POST /out-of-band/receive-invitation
2023-01-09 13:39:30,741 aries_cloudagent.admin.server DEBUG Match info: <MatchInfo {}: <ResourceRoute [POST] <PlainResource  /out-of-band/receive-invitation> -> <function invitation_receive at 0x7f63e35bca60>>
2023-01-09 13:39:30,742 aries_cloudagent.admin.server DEBUG Body: {"invitation": {"@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/out-of-band/1.1/invitation", "@id": "6ebcb4d6-628b-44de-99bf-b30e6f54c258", "services": [{"id": "#inline", "type": "did-communication", "recipientKeys": ["did:key:z6MkrWU3yJioLKhXLmt8PTubfSqeoihJpzWntBhmC6DCCDoo"], "serviceEndpoint": "http://192.168.56.1:10002"}], "label": "Verifier", "requests~attach": [{"@id": "request-0", "mime-type": "application/json", "data": {"json": {"@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/present-proof/1.0/request-presentation", "@id": "0ce52b2d-68af-410b-983b-0a0c17a98e27", "request_presentations~attach": [{"@id": "libindy-request-presentation-0", "mime-type": "application/json", "data": {"base64": "ey...=="}}], "~thread": {"pthid": "6ebcb4d6-628b-44de-99bf-b30e6f54c258"}}}}]}, "invi_msg_id": "6ebcb4d6-628b-44de-99bf-b30e6f54c258", "oob_id": "fe11e3a7-059f-4738-9ee9-d1fd2d91d1a7", "state": "initial", "trace": false, "invitation_url": "http://192.168.56.1:10002?oob=ey...="}
2023-01-09 13:39:30,743 aries_cloudagent.admin.server ERROR Handler error with exception: Unprocessable Entity

=================
Traceback (most recent call last):
  File "/home/indy/.pyenv/versions/3.6.13/lib/python3.6/site-packages/webargs/asyncparser.py", line 90, in parse
    result = schema.load(parsed)
  File "/home/indy/.pyenv/versions/3.6.13/lib/python3.6/site-packages/marshmallow/schema.py", line 723, in load
    data, many=many, partial=partial, unknown=unknown, postprocess=True
  File "/home/indy/.pyenv/versions/3.6.13/lib/python3.6/site-packages/marshmallow/schema.py", line 904, in _do_load
    raise exc
marshmallow.exceptions.ValidationError: {'_schema': ['Model must include non-empty handshake_protocols or requests_attach or both']}

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/indy/.pyenv/versions/3.6.13/lib/python3.6/site-packages/aries_cloudagent/admin/server.py", line 170, in ready_middleware
    return await handler(request)
  File "/home/indy/.pyenv/versions/3.6.13/lib/python3.6/site-packages/aries_cloudagent/admin/server.py", line 207, in debug_middleware
    return await handler(request)
  File "/home/indy/.pyenv/versions/3.6.13/lib/python3.6/site-packages/aiohttp_apispec/middlewares.py", line 34, in validation_middleware
    schema["schema"], request, locations=schema["locations"]
  File "/home/indy/.pyenv/versions/3.6.13/lib/python3.6/site-packages/webargs/asyncparser.py", line 95, in parse
    error, req, schema, error_status_code, error_headers
  File "/home/indy/.pyenv/versions/3.6.13/lib/python3.6/site-packages/webargs/asyncparser.py", line 108, in _on_validation_error
    await error_handler(error, req, schema, error_status_code, error_headers)
  File "/home/indy/.pyenv/versions/3.6.13/lib/python3.6/site-packages/webargs/aiohttpparser.py", line 166, in handle_error
    content_type="application/json",
aiohttp.web_exceptions.HTTPUnprocessableEntity: Unprocessable Entity

As you can see, a requests_attach is set and received. Nevertheless, the holders ACA-Py throws this error. Is this a bug or did I make a mistake?

swcurran commented 1 year ago

@andrewwhitehead -- is this handled by your recent #2060 PR? If not, what is needed to support this. AFAIK, it should be supported according to this table in the OOB RFC, third entry.

kukgini commented 1 year ago

When calling the /out-of-band/receive-invitation API, extract and put only the invitation item in the payload of the request body like this:

{
    "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/out-of-band/1.1/invitation",
    "@id": "6ebcb4d6-628b-44de-99bf-b30e6f54c258",
    "services": [
      {
        "id": "#inline",
        "type": "did-communication",
        "recipientKeys": [
          "did:key:z6MkrWU3yJioLKhXLmt8PTubfSqeoihJpzWntBhmC6DCCDoo"
        ],
        "serviceEndpoint": "http://192.168.56.1:10002"
      }
    ],
    "label": "Verifier",
    "requests~attach": [
      {
        "@id": "request-0",
        "mime-type": "application/json",
        "data": {
          "json": {
            "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/present-proof/1.0/request-presentation",
            "@id": "0ce52b2d-68af-410b-983b-0a0c17a98e27",
            "request_presentations~attach": [
              {
                "@id": "libindy-request-presentation-0",
                "mime-type": "application/json",
                "data": {
                  "base64": "ey...=="
                }
              }
            ],
            "~thread": {
              "pthid": "6ebcb4d6-628b-44de-99bf-b30e6f54c258"
            }
          }
        }
      }
    ]
  }
pstuermlinger commented 1 year ago

@kukgini this worked, thank you!