Ejemplo n.º 1
0
def step_impl(context, inviter: str, invitee: str):
    inviter_url = context.config.userdata.get(inviter)
    invitee_url = context.config.userdata.get(invitee)

    assert inviter in context.connection_id_dict, f'no connection IDs saved for "{inviter}"'
    assert invitee in context.connection_id_dict[inviter], f'no connection ID saved from "{inviter}" to "{invitee}"'
    inviter_connection_id = context.connection_id_dict[inviter][invitee]
    assert invitee in context.connection_id_dict, f'no connection IDs saved for "{invitee}"'
    assert inviter in context.connection_id_dict[invitee], f'no connection ID saved from "{invitee}" to "{inviter}"'
    invitee_connection_id = context.connection_id_dict[invitee][inviter]

    (resp_status, resp_text) = agent_backchannel_GET(
        inviter_url + "/agent/command/",
        "connection",
        id=inviter_connection_id,
    )
    assert resp_status == 200, f"resp_status {resp_status} is not 200; {resp_text}"

    inviter_connection = resp_text

    (resp_status, resp_text) = agent_backchannel_GET(
        invitee_url + "/agent/command/",
        "connection",
        id=invitee_connection_id,
    )
    assert resp_status == 200, f"resp_status {resp_status} is not 200; {resp_text}"

    invitee_connection = resp_text
def step_impl(context, issuer):

    issuer_url = context.config.userdata.get(issuer)

    credential_revocation = {
        "cred_rev_id": context.cred_rev_id,
        "rev_registry_id": context.rev_reg_id,
        "publish_immediately": True,
    }

    (resp_status, resp_text) = agent_backchannel_POST(issuer_url + "/agent/command/", "revocation", operation="revoke", data=credential_revocation)
    assert resp_status == 200, f'resp_status {resp_status} is not 200; {resp_text}'
    #resp_json = json.loads(resp_text)

    # Check the Holder wallet for the credential
    # Should be a 200 since the revoke doesn't remove the cred from the holders wallet. 
    # What else to check?
    (resp_status, resp_text) = agent_backchannel_GET(context.config.userdata.get(context.holder_name) + "/agent/command/", "credential", id=context.credential_id_dict[context.schema['schema_name']][len(context.credential_id_dict[context.schema['schema_name']])-1])
    assert resp_status == 200, f'resp_status {resp_status} is not 200; {resp_text}'

    # if this is ACA-py then there is provision for the holder to check the revocation status of the cred then they can take action,
    # like delete it from thier wallet. This should be done, since the algorithm that 
    if "delete_cred_from_wallet" in context.tags:
        # Call the revocation status api
        #(resp_status, resp_text) = agent_backchannel_GET(context.prover_url + "/agent/command/", "revocation", operation="credential-record", data=credential_revocation)
        (resp_status, resp_text) = agent_backchannel_GET(context.prover_url + "/agent/command/", "credential", operation="revoked", id=context.credential_id_dict[context.schema['schema_name']][len(context.credential_id_dict[context.schema['schema_name']])-1])
        assert resp_status == 200, f'resp_status {resp_status} is not 200; {resp_text}'
        # get the credential status verified out of the response
        # Could also add the cred status to the cred id dict. Maybe later if needed.
        resp_json = json.loads(resp_text)
        revoked = resp_json["revoked"]
        if revoked == True:
            # Call the delete on the credential in the wallet 
            (resp_status, resp_text) = agent_backchannel_DELETE(context.prover_url + "/agent/command/", "credential", id=context.credential_id_dict[context.schema['schema_name']][len(context.credential_id_dict[context.schema['schema_name']])-1])
            assert resp_status == 200, f'resp_status {resp_status} is not 200; {resp_text}'
Ejemplo n.º 3
0
def step_impl(context, holder):

        holder_url = context.config.userdata.get(holder)
        # get the credential from the holders wallet
        (resp_status, resp_text) = agent_backchannel_GET(holder_url + "/agent/command/", "credential", id=context.credential_id_dict[context.schema['schema_name']])
        assert resp_status == 200, f'resp_status {resp_status} is not 200; {resp_text}'
        resp_json = json.loads(resp_text)
        assert resp_json["referent"] == context.credential_id_dict[context.schema['schema_name']]
        assert resp_json["schema_id"] == context.issuer_schema_id_dict[context.schema["schema_name"]]
        assert resp_json["cred_def_id"] == context.credential_definition_id_dict[context.schema["schema_name"]]

        # Make sure the issuer is not holding the credential
        # get the credential from the holders wallet
        (resp_status, resp_text) = agent_backchannel_GET(context.issuer_url + "/agent/command/", "credential", id=context.credential_id_dict[context.schema['schema_name']])
        assert resp_status == 404, f'resp_status {resp_status} is not 404; {resp_text}'
Ejemplo n.º 4
0
def step_impl(context, requester, responder):
    requester_url = context.config.userdata.get(requester)

    requester_did = context.requester_did

    data = {
        "their_public_did": requester_did
    }

    (resp_status, resp_text) = agent_backchannel_POST(requester_url + "/agent/command/", "did-exchange", operation="create-request-resolvable-did", data=data)
    assert resp_status == 200, f'resp_status {resp_status} is not 200; {resp_text}'

    resp_json = json.loads(resp_text)
    requester_did_doc = resp_json

    context.requester_public_did_doc = requester_did_doc

    # get the requesters connection id
    request_id = context.requester_public_did_doc["@id"]
    (resp_status, resp_text) = agent_backchannel_GET(requester_url + "/agent/response/", "did-exchange", id=request_id)
    assert resp_status == 200, f'resp_status {resp_status} is not 200; {resp_text}'
    resp_json = json.loads(resp_text)

    # setup the initial connection id dictionary if one doesn't exist.
    if not hasattr(context, 'connection_id_dict'):
        context.connection_id_dict = {}

    # Check for responder key existing in dict
    if requester not in context.connection_id_dict:
        context.connection_id_dict[requester] = {}

    # Some agents (afgo) do not have a webhook that give a connection id at this point in the protocol. 
    # If it is not here, skip this and check for one later in the process and add it then.
    if "connection_id" in resp_text:
        context.connection_id_dict[requester][context.responder_name] = resp_json["connection_id"]
def step_impl(context, responder):
    responder_url = context.config.userdata.get(responder)

    # If the connection id dict is not populated for the responder to requester relationship, it means the agent in use doesn't
    # support giving the responders connection_id before the send-request
    # Make a call to the responder for the connection id and add it to the collection
    if context.requester_name not in context.connection_id_dict[responder]:
        # One way (maybe preferred) to get the connection id is to get it from the probable webhook that the controller gets because of the previous step
        invitation_id = context.responder_invitation["@id"]
        (resp_status,
         resp_text) = agent_backchannel_GET(responder_url + "/agent/response/",
                                            "did-exchange",
                                            id=invitation_id)
        assert resp_status == 200, f'resp_status {resp_status} is not 200; {resp_text}'
        resp_json = json.loads(resp_text)

        # The second way to do this is to call the connection protocol for the connection id given the invitation_id or a thread id.
        # This method is disabled for now, will be enabled if afgo can't get the connection id for the webhook above.
        #(resp_status, resp_text) = agent_backchannel_GET(responder_url + "/agent/command/", connections, id=invitation_id)

        if "connection_id" in resp_text:
            context.connection_id_dict[responder][
                context.requester_name] = resp_json["connection_id"]

    responder_connection_id = context.connection_id_dict[responder][
        context.requester_name]

    # responder already recieved the connection request in the send-request call so get connection and verify status.
    #assert expected_agent_state(responder_url, "didexchange", responder_connection_id, "request-recieved")
    #invitation_id = context.responder_invitation["@id"]
    assert expected_agent_state(responder_url, "connection",
                                responder_connection_id, "request-received")
Ejemplo n.º 6
0
def step_impl(context, issuer):
    issuer_url = context.config.userdata.get(issuer)

    (resp_status,
     resp_text) = agent_backchannel_GET(issuer_url + "/agent/command/", "did")
    assert resp_status == 200, f'resp_status {resp_status} is not 200; {resp_text}'

    resp_json = json.loads(resp_text)
    issuer_did = resp_json

    if "schema" not in context:
        # check for a schema already loaded in the context. If it is not, load the template
        if "schema" not in context:
            context.schema = SCHEMA_TEMPLATE.copy()
            context.schema[
                "schema_name"] = context.schema["schema_name"] + issuer

    #context.issuer_did = issuer_did["did"]
    if 'issuer_did_dict' in context:
        context.issuer_did_dict[
            context.schema['schema_name']] = issuer_did["did"]
    else:
        context.issuer_did_dict = {
            context.schema['schema_name']: issuer_did["did"]
        }
Ejemplo n.º 7
0
def step_impl(context, holder):

    holder_url = context.config.userdata.get(holder)
    # get the credential from the holders wallet
    (resp_status, resp_text) = agent_backchannel_GET(
        holder_url + "/agent/command/",
        "credential",
        id=context.credential_id_dict[context.schema["schema_name"]]
        [len(context.credential_id_dict[context.schema["schema_name"]]) - 1],
    )
    assert resp_status == 200, f"resp_status {resp_status} is not 200; {resp_text}"
    resp_json = json.loads(resp_text)
    if "state" in resp_json and resp_json["state"] == "N/A":
        # backchannel can't get the credential
        pass
    else:
        schema_name = context.schema["schema_name"]
        credentials = context.credential_id_dict[schema_name]

        # Check with last credential id
        assert resp_json["referent"] == credentials[-1]
        # Some agents don't return or have a schema id or cred_def_id, so only check it it exists.
        if "schema_id" in resp_json:
            assert resp_json["schema_id"] == context.issuer_schema_id_dict[
                schema_name]
        if "cred_def_id" in resp_json:
            assert (resp_json["cred_def_id"] ==
                    context.credential_definition_id_dict[schema_name])
Ejemplo n.º 8
0
def step_impl(context, responder):
    responder_url = context.config.userdata.get(responder)

    # If the connection id dict is not populated for the responder to requester relationship, it means the agent in use doesn't
    # support giving the responders connection_id before the send-request
    # Make a call to the responder for the connection id and add it to the collection
    if context.requester_name not in context.connection_id_dict[responder]:
        # One way (maybe preferred) to get the connection id is to get it from the probable webhook that the controller gets because of the previous step
        invitation_id = context.responder_invitation["@id"]
        time.sleep(0.5)  # delay for webhook to execute
        (resp_status,
         resp_text) = agent_backchannel_GET(responder_url + "/agent/response/",
                                            "did-exchange",
                                            id=invitation_id)  # {}
        assert resp_status == 200, f"resp_status {resp_status} is not 200; {resp_text}"
        resp_json = json.loads(resp_text)

        # The second way to do this is to call the connection protocol for the connection id given the invitation_id or a thread id.
        # This method is disabled for now, will be enabled if afgo can't get the connection id for the webhook above.
        # (resp_status, resp_text) = agent_backchannel_GET(responder_url + "/agent/command/", connections, id=invitation_id)

        if "connection_id" in resp_text:
            context.connection_id_dict[responder][
                context.requester_name] = resp_json["connection_id"]
        else:
            assert False, f"Could not retreive responders connection_id"
Ejemplo n.º 9
0
def step_impl(context, responder: str):
    responder_url = context.config.userdata.get(responder)

    # If the connection id dict is not populated for the responder to requester relationship, it means the agent in use doesn't
    # support giving the responders connection_id before the send-request
    # Make a call to the responder for the connection id and add it to the collection
    if context.requester_name not in context.connection_id_dict[responder]:
        # One way (maybe preferred) to get the connection id is to get it from the probable webhook that the controller gets because of the previous step
        invitation_id = context.responder_invitation["@id"]
        time.sleep(0.5)  # delay for webhook to execute
        (resp_status,
         resp_text) = agent_backchannel_GET(responder_url + "/agent/response/",
                                            "did-exchange",
                                            id=invitation_id)  # {}
        assert resp_status == 200, f"resp_status {resp_status} is not 200; {resp_text}"
        resp_json = json.loads(resp_text)

        if "connection_id" not in resp_text:
            # If we weren't able to find the connection_id it means the request
            # probably never arrived. We don't have to do a check
            return

        context.connection_id_dict[responder][
            context.requester_name] = resp_json["connection_id"]

    # Check the request never arrived
    assert expected_agent_state(
        responder_url, "did-exchange",
        context.connection_id_dict[responder][context.requester_name],
        ["invitation-sent"])
Ejemplo n.º 10
0
def step_impl(context, requester: str, responder: str):
    requester_url = context.config.userdata.get(requester)

    requester_did = context.requester_did

    data = {"their_public_did": requester_did, "their_did": requester_did}

    (resp_status, resp_text) = agent_backchannel_POST(
        requester_url + "/agent/command/",
        "did-exchange",
        operation="create-request-resolvable-did",
        data=data,
    )
    assert resp_status == 200, f"resp_status {resp_status} is not 200; {resp_text}"

    resp_json = json.loads(resp_text)
    requester_did_doc = resp_json

    context.requester_public_did_doc = requester_did_doc

    if "connection_id" not in resp_json:
        # get the requesters connection id
        request_id = context.requester_public_did_doc["@id"]
        (resp_status,
         resp_text) = agent_backchannel_GET(requester_url + "/agent/response/",
                                            "did-exchange",
                                            id=request_id)
        assert resp_status == 200, f"resp_status {resp_status} is not 200; {resp_text}"
        resp_json = json.loads(resp_text)

    # Some agents (afgo) do not have a webhook that give a connection id at this point in the protocol.
    # If it is not here, skip this and check for one later in the process and add it then.
    if "connection_id" in resp_text:
        context.connection_id_dict[requester][responder] = resp_json[
            "connection_id"]
Ejemplo n.º 11
0
def step_impl(context, requester):
    requester_url = context.config.userdata.get(requester)

    (resp_status, resp_text) = agent_backchannel_GET(requester_url + "/agent/command/", "did")
    assert resp_status == 200, f'resp_status {resp_status} is not 200; {resp_text}'

    resp_json = json.loads(resp_text)
    context.requester_public_did = resp_json
def step_impl(context, invitee):
    invitee_url = context.config.userdata.get(invitee)

    data = context.inviter_invitation

    # If mediator is set for the current connection, set the mediator_connection_id
    mediator = context.mediator_dict.get(invitee)
    if mediator:
        data["mediator_connection_id"] = context.connection_id_dict[invitee][
            mediator]

    (resp_status, resp_text) = agent_backchannel_POST(
        invitee_url + "/agent/command/",
        "connection",
        operation="receive-invitation",
        data=data,
    )
    assert resp_status == 200, f"resp_status {resp_status} is not 200; {resp_text}"

    resp_json = json.loads(resp_text)

    context.connection_id_dict[invitee][
        context.inviter_name] = resp_json["connection_id"]

    # Also add the inviter into the main connection_id_dict. if the len is 0 that means its already been cleared and this may be Mallory.
    if len(context.temp_connection_id_dict) != 0:
        context.connection_id_dict[context.inviter_name][
            invitee] = context.temp_connection_id_dict[context.inviter_name]
        # clear the temp connection id dict used in the initial step. We don't need it anymore.
        context.temp_connection_id_dict.clear()
    else:
        # This means the connection id was not retreived for the inviter in the create invitation step
        # Get the connection id for the inviter given the invitation_id
        (alt_resp_status, alt_resp_text) = agent_backchannel_GET(
            context.inviter_url + "/agent/response/",
            "connection",
            id=context.inviter_invitation["@id"],
        )
        assert (alt_resp_status == 200
                ), f"resp_status {alt_resp_status} is not 200; {alt_resp_text}"
        alt_resp_json = json.loads(alt_resp_text)
        context.connection_id_dict[
            context.inviter_name][invitee] = alt_resp_json["connection_id"]

    # Check to see if the invitee_name exists in context. If not, antother suite is using it so set the invitee name and url
    if not context.invitee_name:
        context.invitee_url = invitee_url
        context.invitee_name = invitee

    # get connection and verify status
    assert expected_agent_state(
        invitee_url,
        "connection",
        context.connection_id_dict[invitee][context.inviter_name],
        "invited",
    )
Ejemplo n.º 13
0
def step_impl(context, issuer):
    issuer_url = context.config.userdata.get(issuer)

    (resp_status,
     resp_text) = agent_backchannel_GET(issuer_url + "/agent/command/", "did")
    assert resp_status == 200, f'resp_status {resp_status} is not 200; {resp_text}'

    resp_json = json.loads(resp_text)
    issuer_did = resp_json

    context.issuer_did = issuer_did["did"]
def step_impl(context, holder, cred_format):
    holder_url = context.config.userdata.get(holder)

    # a credential id shouldn't be needed with a cred_ex_id being passed
    # credential_id = {
    #     "credential_id": context.cred_thread_id,
    # }
    credential_id = {"comment": "storing credential"}

    sleep(1)
    (resp_status,
     resp_text) = agent_backchannel_POST(holder_url + "/agent/command/",
                                         "issue-credential-v2",
                                         operation="store",
                                         id=context.cred_thread_id,
                                         data=credential_id)
    assert resp_status == 200, f'resp_status {resp_status} is not 200; {resp_text}'
    resp_json = json.loads(resp_text)
    assert resp_json["state"] == "done"

    #credential_id = resp_json[cred_format]["credential_id"]
    credential_id = resp_json["cred_ex_record"]["cred_id_stored"]

    if 'credential_id_dict' in context:
        try:
            context.credential_id_dict[context.schema['schema_name']].append(
                credential_id)
        except KeyError:
            context.credential_id_dict[context.schema['schema_name']] = [
                credential_id
            ]
    else:
        context.credential_id_dict = {
            context.schema['schema_name']: [credential_id]
        }

    # Verify issuer status
    # TODO This is returning none instead of Done. Should this be the case. Needs investigation.
    #assert expected_agent_state(context.issuer_url, "issue-credential-v2", context.cred_thread_id, "done")

    # if the credential supports revocation, get the Issuers webhook callback JSON from the store command
    # From that JSON save off the credential revocation identifier, and the revocation registry identifier.
    if "support_revocation" in context:
        if context.support_revocation:
            (resp_status, resp_text) = agent_backchannel_GET(
                context.config.userdata.get(context.issuer_name) +
                "/agent/response/",
                "revocation-registry",
                id=context.cred_thread_id)
            assert resp_status == 200, f'resp_status {resp_status} is not 200; {resp_text}'
            resp_json = json.loads(resp_text)
            context.cred_rev_id = resp_json["revocation_id"]
            context.rev_reg_id = resp_json["revoc_reg_id"]
Ejemplo n.º 15
0
def step_impl(context, issuer):
    issuer_url = context.config.userdata.get(issuer)
    issuer_schema_id = context.issuer_schema_id_dict[context.schema['schema_name']]

    (resp_status, resp_text) = agent_backchannel_GET(issuer_url + "/agent/command/", "schema", id=issuer_schema_id)
    assert resp_status == 200, f'resp_status {resp_status} is not 200; {resp_text}'

    resp_json = json.loads(resp_text)
    #context.issuer_schema = resp_json
    if 'issuer_schema_dict' in context:
        context.issuer_schema_dict[context.schema['schema_name']] = resp_json
    else:
        context.issuer_schema_dict = {context.schema['schema_name']: resp_json}
Ejemplo n.º 16
0
def step_impl(context, invitee):
    invitee_url = context.config.userdata.get(invitee)

    data = context.inviter_invitation
    (resp_status,
     resp_text) = agent_backchannel_POST(invitee_url + "/agent/command/",
                                         "connection",
                                         operation="receive-invitation",
                                         data=data)
    assert resp_status == 200, f'resp_status {resp_status} is not 200; {resp_text}'

    resp_json = json.loads(resp_text)

    if not hasattr(context, 'connection_id_dict'):
        context.connection_id_dict = {}
        context.connection_id_dict[invitee] = {}

    context.connection_id_dict[invitee][
        context.inviter_name] = resp_json["connection_id"]

    # Also add the inviter into the main connection_id_dict. if the len is 0 that means its already been cleared and this may be Mallory.
    if "temp_connection_id_dict" in context:
        if len(context.temp_connection_id_dict) != 0:
            context.connection_id_dict[context.inviter_name] = {
                invitee: context.temp_connection_id_dict[context.inviter_name]
            }
            #clear the temp connection id dict used in the initial step. We don't need it anymore.
            context.temp_connection_id_dict.clear()
    else:
        # This means the connection id was not retreived for the inviter in the create invitation step
        # Get the connection id for the inviter given the invitation_id
        #context.connection_id_dict[context.inviter_name] = {invitee:  resp_json["connection_id"]}
        (alt_resp_status, alt_resp_text) = agent_backchannel_GET(
            context.inviter_url + "/agent/response/",
            "connection",
            id=context.inviter_invitation["@id"])
        assert alt_resp_status == 200, f'resp_status {alt_resp_status} is not 200; {alt_resp_text}'
        alt_resp_json = json.loads(alt_resp_text)
        context.connection_id_dict[context.inviter_name] = {
            invitee: alt_resp_json["connection_id"]
        }

    # Check to see if the invitee_name exists in context. If not, another suite is using it so set the invitee name and url
    if not hasattr(context, 'invitee_name'):
        context.invitee_url = invitee_url
        context.invitee_name = invitee

    # get connection and verify status
    assert expected_agent_state(
        invitee_url, "connection",
        context.connection_id_dict[invitee][context.inviter_name], "invited")
Ejemplo n.º 17
0
def step_impl(context, issuer):
    issuer_url = context.config.userdata.get(issuer)
    issuer_schema_id = context.issuer_schema_id_dict[
        context.schema["schema_name"]]

    (resp_status,
     resp_text) = agent_backchannel_GET(issuer_url + "/agent/command/",
                                        "schema",
                                        id=issuer_schema_id)
    assert resp_status == 200, f"resp_status {resp_status} is not 200; {resp_text}"

    resp_json = json.loads(resp_text)

    context.issuer_schema_dict[context.schema["schema_name"]] = resp_json
Ejemplo n.º 18
0
def step_impl(context, issuer):
    issuer_url = context.config.userdata.get(issuer)
    issuer_credential_definition_id = context.credential_definition_id

    (resp_status,
     resp_text) = agent_backchannel_GET(issuer_url + "/agent/command/",
                                        "credential-definition",
                                        id=issuer_credential_definition_id)
    assert resp_status == 200, f'resp_status {resp_status} is not 200; {resp_text}'

    resp_json = json.loads(resp_text)
    issuer_credential_definition = resp_json

    context.issuer_credential_definition = issuer_credential_definition
Ejemplo n.º 19
0
def step_impl(context, responder: str, requester: str):
    responder_url = context.config.userdata.get(responder)

    data = {"use_public_did": False}

    # If mediator is set for the current connection, set the mediator_connection_id
    mediator = context.mediator_dict.get(responder)
    if mediator:
        data["mediator_connection_id"] = context.connection_id_dict[responder][
            mediator]

    (resp_status, resp_text) = agent_backchannel_POST(
        responder_url + "/agent/command/",
        "out-of-band",
        operation="send-invitation-message",
        data=data,
    )
    assert resp_status == 200, f"resp_status {resp_status} is not 200; {resp_text}"

    resp_json = json.loads(resp_text)
    assert resp_json["state"] == "invitation-sent"
    context.responder_invitation = resp_json["invitation"]
    # TODO drill into the handshake protocol in the invitation and remove anything else besides didexchange.

    # Get the responders's connection id from the above request's response webhook in the backchannel
    invitation_id = context.responder_invitation["@id"]
    (resp_status,
     resp_text) = agent_backchannel_GET(responder_url + "/agent/response/",
                                        "did-exchange",
                                        id=invitation_id)
    assert resp_status == 200, f"resp_status {resp_status} is not 200; {resp_text}"
    resp_json = json.loads(resp_text)

    # Some agents (afgo) do not have a webhook that give a connection id at this point in the protocol.
    # If it is not here, skip this and check for one later in the process and add it then.
    if "connection_id" in resp_text:
        context.connection_id_dict[responder][requester] = resp_json[
            "connection_id"]

    # Check to see if the responder name is the same as this person. If not, it is a 3rd person acting as an issuer that needs a connection
    # TODO: it would be nicer to pass the names on every call to remove the need for global keeping of who's the requester / responder
    if context.responder_name != responder:
        context.responder_name = responder
        context.responder_url = responder_url
    if context.requester_name != requester:
        context.requester_name = requester
        context.requester_url = context.config.userdata.get(requester)
Ejemplo n.º 20
0
def step_impl(context, inviter: str, invitee: str):
    inviter_url = context.config.userdata.get(inviter)

    invitation = context.invitation_v2[inviter]
    invitation_id = invitation["id"]

    (resp_status, resp_text) = agent_backchannel_GET(
        inviter_url + "/agent/command/",
        "oob-v2",
        operation="invitation-connection",
        id=invitation_id,
    )
    assert resp_status == 200, f"resp_status {resp_status} is not 200; {resp_text}"

    resp_json = json.loads(resp_text)

    context.connection_id_dict[inviter][invitee] = resp_json["connection_id"]
def step_impl(context, issuer):
    issuer_url = context.config.userdata.get(issuer)

    (resp_status,
     resp_text) = agent_backchannel_GET(issuer_url + "/agent/command/",
                                        "issue-credential-v3",
                                        id="retrieve-credential-proposal")

    credential_proposal = json.loads(resp_text)

    pthid_from_proposal = credential_proposal["pthid"]

    expected_pthid = context.invitation_v2[issuer]["id"]

    assert pthid_from_proposal == expected_pthid, \
        f"Failed to correlate the credential proposal with the out of band invitation. " \
        f"The pthid in the proposal is {pthid_from_proposal} but {expected_pthid} was expected."
def step_impl(context, issuer):
    issuer_url = context.config.userdata.get(issuer)

    (resp_status,
     resp_text) = agent_backchannel_GET(issuer_url + "/agent/command/",
                                        "issue-credential-v3",
                                        id="retrieve-credential-application")

    assert resp_status == 200, f'resp_status {resp_status} is not 200; {resp_text}'

    credential_application_attachment = json.loads(resp_text)

    manifest_id_in_credential_application = credential_application_attachment[
        "credential_application"]["manifest_id"]

    assert manifest_id_in_credential_application == context.manifest_id, \
        f"Credential Manifest ID in the received Credential Application ({manifest_id_in_credential_application}) " \
        f"is unknown. Was expecting {context.manifest_id}"
def step_impl(context, responder):
    responder_url = context.config.userdata.get(responder)

    # If the connection id dict is not populated for the responder to requester relationship, it means the agent in use doesn't
    # support giving the responders connection_id before the send-request
    # Make a call to the responder for the connection id and add it to the collection
    if context.requester_name not in context.connection_id_dict[responder]:
        # One way (maybe preferred) to get the connection id is to get it from the probable webhook that the controller gets because of the previous step
        invitation_id = context.responder_invitation["@id"]
        time.sleep(0.5)  # delay for webhook to execute
        (resp_status,
         resp_text) = agent_backchannel_GET(responder_url + "/agent/response/",
                                            "did-exchange",
                                            id=invitation_id)  # {}
        assert resp_status == 200, f'resp_status {resp_status} is not 200; {resp_text}'
        resp_json = json.loads(resp_text)

        # The second way to do this is to call the connection protocol for the connection id given the invitation_id or a thread id.
        # This method is disabled for now, will be enabled if afgo can't get the connection id for the webhook above.
        #(resp_status, resp_text) = agent_backchannel_GET(responder_url + "/agent/command/", connections, id=invitation_id)

        if "connection_id" in resp_text:
            context.connection_id_dict[responder][
                context.requester_name] = resp_json["connection_id"]
        else:
            assert False, f'Could not retreive responders connection_id'

            # It is probably the case that we are dealing with a Public DID invitation that does not have the webhook message keyed on
            # invitation_id. In this case, try to grab the latest unkeyed message off of the webhook queue.
            # see issue 944 for full details https://app.zenhub.com/workspaces/von---verifiable-organization-network-5adf53987ccbaa70597dbec0/issues/hyperledger/aries-cloudagent-python/944
            # (resp_status, resp_text) = agent_backchannel_GET(responder_url + "/agent/response/", "did-exchange")
            # assert resp_status == 200, f'resp_status {resp_status} is not 200; {resp_text}'
            # resp_json = json.loads(resp_text)
            # if "connection_id" in resp_text:
            #     context.connection_id_dict[responder][context.requester_name] = resp_json["connection_id"]
            # else:
            #     assert False, f'Could not retreive responders connection_id'

    responder_connection_id = context.connection_id_dict[responder][
        context.requester_name]

    # responder already recieved the connection request in the send-request call so get connection and verify status.
    assert expected_agent_state(responder_url, "did-exchange",
                                responder_connection_id, "request-received")
def step_impl(context, responder):
    responder_url = context.config.userdata.get(responder)

    data = {"use_public_did": False}

    (resp_status,
     resp_text) = agent_backchannel_POST(responder_url + "/agent/command/",
                                         "out-of-band",
                                         operation="send-invitation-message",
                                         data=data)
    assert resp_status == 200, f'resp_status {resp_status} is not 200; {resp_text}'

    resp_json = json.loads(resp_text)
    assert resp_json["state"] == "invitation-sent"
    #assert "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/didexchange/v1.0" in resp_text
    context.responder_invitation = resp_json["invitation"]
    # TODO drill into the handshake protocol in the invitation and remove anything else besides didexchange.

    # setup the initial connection id dictionary if one doesn't exist.
    if not hasattr(context, 'connection_id_dict'):
        context.connection_id_dict = {}

    # Check for responder key existing in dict
    if responder not in context.connection_id_dict:
        context.connection_id_dict[responder] = {}

    # Get the responders's connection id from the above request's response webhook in the backchannel
    invitation_id = context.responder_invitation["@id"]
    (resp_status,
     resp_text) = agent_backchannel_GET(responder_url + "/agent/response/",
                                        "did-exchange",
                                        id=invitation_id)
    assert resp_status == 200, f'resp_status {resp_status} is not 200; {resp_text}'
    resp_json = json.loads(resp_text)

    # Some agents (afgo) do not have a webhook that give a connection id at this point in the protocol.
    # If it is not here, skip this and check for one later in the process and add it then.
    if "connection_id" in resp_text:
        context.connection_id_dict[responder][
            context.requester_name] = resp_json["connection_id"]

    # Check to see if the responder name is the same as this person. If not, it is a 3rd person acting as an issuer that needs a connection
    if context.responder_name != responder:
        context.responder_name = responder
Ejemplo n.º 25
0
def step_impl(context, holder):
    holder_url = context.config.userdata.get(holder)

    # a credential id shouldn't be needed with a cred_ex_id being passed
    credential_id = {
        "credential_id": context.cred_thread_id,
    }

    # (resp_status, resp_text) = agent_backchannel_POST(holder_url + "/agent/command/", "credential", operation="store", id=context.holder_cred_ex_id)
    sleep(3)
    (resp_status, resp_text) = agent_backchannel_POST(
        holder_url + "/agent/command/",
        "issue-credential",
        operation="store",
        id=context.cred_thread_id,
        data=credential_id,
    )
    assert resp_status == 200, f"resp_status {resp_status} is not 200; {resp_text}"
    resp_json = json.loads(resp_text)
    assert resp_json["state"] == "done"

    # Store credential id
    context.credential_id_dict[context.schema["schema_name"]].append(
        resp_json["credential_id"])

    # Verify issuer status
    # This is returning none instead of Done. Should this be the case. Needs investigation.
    # assert expected_agent_state(context.issuer_url, "issue-credential", context.cred_thread_id, "done")

    # if the credential supports revocation, get the Issuers webhook callback JSON from the store command
    # From that JSON save off the credential revocation identifier, and the revocation registry identifier.
    if context.support_revocation:
        (resp_status, resp_text) = agent_backchannel_GET(
            context.config.userdata.get(context.issuer_name) +
            "/agent/response/",
            "revocation-registry",
            id=context.cred_thread_id,
        )
        assert resp_status == 200, f"resp_status {resp_status} is not 200; {resp_text}"
        resp_json = json.loads(resp_text)
        context.cred_rev_id = resp_json["revocation_id"]
        context.rev_reg_id = resp_json["revoc_reg_id"]
def step_impl(context, holder, cred_format):
    holder_url = context.config.userdata.get(holder)

    # get the credential from the holders wallet
    (resp_status, resp_text) = agent_backchannel_GET(
        holder_url + "/agent/command/",
        "credential",
        id=context.credential_id_dict[context.schema['schema_name']][-1])
    assert resp_status == 200, f'resp_status {resp_status} is not 200; {resp_text}'
    resp_json = json.loads(resp_text)

    if cred_format == CRED_FORMAT_INDY:
        #assert resp_json["schema_id"] == context.issuer_schema_id_dict[context.schema["schema_name"]]
        #assert resp_json["cred_def_id"] == context.credential_definition_id_dict[context.schema["schema_name"]]
        assert resp_json["referent"] == context.credential_id_dict[
            context.schema['schema_name']][-1]
    elif cred_format == CRED_FORMAT_JSON_LD:
        # TODO: do not use schema name for credential_id_dict
        assert resp_json["credential_id"] == context.credential_id_dict[
            context.schema['schema_name']][-1]
Ejemplo n.º 27
0
def step_impl(context, responder: str, requester: str):
    responder_url = context.config.userdata.get(responder)

    data = {"use_public_did": True}

    (resp_status, resp_text) = agent_backchannel_POST(
        responder_url + "/agent/command/",
        "out-of-band",
        operation="send-invitation-message",
        data=data,
    )
    assert resp_status == 200, f"resp_status {resp_status} is not 200; {resp_text}"

    resp_json = json.loads(resp_text)
    assert resp_json["state"] == "invitation-sent"
    # assert "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/didexchange/v1.0" in resp_text
    context.responder_invitation = resp_json["invitation"]
    # TODO drill into the handshake protocol in the invitation and remove anything else besides didexchange.

    # Get the responders's connection id from the above request's response webhook in the backchannel
    invitation_id = context.responder_invitation["@id"]
    (resp_status,
     resp_text) = agent_backchannel_GET(responder_url + "/agent/response/",
                                        "did-exchange",
                                        id=invitation_id)
    assert resp_status == 200, f"resp_status {resp_status} is not 200; {resp_text}"
    resp_json = json.loads(resp_text)

    if "connection_id" in resp_text:
        context.connection_id_dict[responder][requester] = resp_json[
            "connection_id"]

    # Check to see if the responder name is the same as this person. If not, it is a 3rd person acting as an issuer that needs a connection
    # TODO: it would be nicer to pass the names on every call to remove the need for global keeping of who's the requester / responder
    if context.responder_name != responder:
        context.responder_name = responder
        context.responder_url = responder_url
    if context.requester_name != requester:
        context.requester_name = requester
        context.requester_url = context.config.userdata.get(requester)
Ejemplo n.º 28
0
def step_impl(context, holder):
    holder_url = context.holder_url

    # If @indy then we can be sure we cannot start the protocol from this command. We can be sure that we have previously
    # gotten the cred_ex_id or have a thread_id.
    if "Indy" in context.tags:
        sleep(1)
        (resp_status,
         resp_text) = agent_backchannel_POST(holder_url + "/agent/command/",
                                             "issue-credential",
                                             operation="send-request",
                                             id=context.holder_cred_ex_id)

    # We are starting from here in the protocol so you won't have the cred_ex_id or the thread_id
    else:
        (resp_status, resp_text) = agent_backchannel_POST(
            holder_url + "/agent/command/",
            "issue-credential",
            operation="send-request",
            id=context.connection_id_dict[holder])

    assert resp_status == 200, f'resp_status {resp_status} is not 200; {resp_text}'
    resp_json = json.loads(resp_text)
    assert resp_json["state"] == "request_sent"

    # Check the state of the issuer through the webhook
    sleep(
        1
    )  # It seems like you have to wait here for a moment in order to wait for the webhook to happen.
    (resp_status, resp_text) = agent_backchannel_GET(context.issuer_url +
                                                     "/agent/response/",
                                                     "issue-credential",
                                                     id=context.cred_thread_id)
    assert resp_status == 200, f'resp_status {resp_status} is not 200; {resp_text}'
    resp_json = json.loads(resp_text)
    # Need to log a bug for this. It should be "request_recieved"
    #assert resp_json["state"] == "request_recieved" #its in offer_sent
    assert resp_json["state"] == "offer_sent"
Ejemplo n.º 29
0
def step_impl(context, holder):

    holder_url = context.config.userdata.get(holder)
    # get the credential from the holders wallet
    (resp_status, resp_text) = agent_backchannel_GET(
        holder_url + "/agent/command/",
        "credential",
        id=context.credential_id_dict[context.schema['schema_name']]
        [len(context.credential_id_dict[context.schema['schema_name']]) - 1])
    assert resp_status == 200, f'resp_status {resp_status} is not 200; {resp_text}'
    resp_json = json.loads(resp_text)
    if "state" in resp_json and resp_json["state"] == "N/A":
        # backchannel can't get the credential
        pass
    else:
        assert resp_json["referent"] == context.credential_id_dict[
            context.schema['schema_name']][len(context.credential_id_dict[
                context.schema['schema_name']]) - 1]
        assert resp_json["schema_id"] == context.issuer_schema_id_dict[
            context.schema["schema_name"]]
        assert resp_json[
            "cred_def_id"] == context.credential_definition_id_dict[
                context.schema["schema_name"]]
Ejemplo n.º 30
0
def step_impl(context, holder, cred_format):
    holder_url = context.config.userdata.get(holder)

    sleep(1)
    (resp_status, resp_text) = agent_backchannel_POST(
        holder_url + "/agent/command/",
        "issue-credential-v2",
        operation="store",
        id=context.cred_thread_id,
    )
    assert resp_status == 200, f"resp_status {resp_status} is not 200; {resp_text}"
    resp_json = json.loads(resp_text)
    state = resp_json["state"]
    assert state == "done", f"state is '{state}', expected 'done'"

    # FIXME: the return value of this is very ACA-Py specific, should just be credential_id
    credential_id = resp_json[cred_format]["credential_id"]
    context.credential_id_dict[context.schema["schema_name"]].append(
        credential_id)

    # Verify issuer status
    # TODO This is returning none instead of Done. Should this be the case. Needs investigation.
    # assert expected_agent_state(context.issuer_url, "issue-credential-v2", context.cred_thread_id, "done")

    # if the credential supports revocation, get the Issuers webhook callback JSON from the store command
    # From that JSON save off the credential revocation identifier, and the revocation registry identifier.
    if context.support_revocation:
        (resp_status, resp_text) = agent_backchannel_GET(
            context.config.userdata.get(context.issuer_name) +
            "/agent/response/",
            "revocation-registry",
            id=context.cred_thread_id,
        )
        assert resp_status == 200, f"resp_status {resp_status} is not 200; {resp_text}"
        resp_json = json.loads(resp_text)
        context.cred_rev_id = resp_json["revocation_id"]
        context.rev_reg_id = resp_json["revoc_reg_id"]