Exemple #1
0
    async def _handle_verify_proof(self, request: IndyVerifyProofReq):
        """
        Verify a proof returned by TheOrgBook

        Args:
            request: the request to verify a proof
        """
        verifier = await self._get_verifier()
        result = await verifier.verify_proof(request.proof_req, request.proof)
        parsed_proof = revealed_attrs(request.proof)

        return IndyVerifiedProof(result, parsed_proof)
Exemple #2
0
async def test_wrappers_with_trust_anchor(pool_ip):
    agent_profiles = [
        'trust-anchor', 'sri', 'pspc-org-book', 'bc-org-book', 'bc-registrar'
    ]

    # 0. configure
    cfg = {}
    parser = ConfigParser()
    ini = pjoin(dirname(dirname(abspath(__file__))), 'app', 'config',
                'config.ini')
    assert isfile(ini)
    with open(ini, 'r') as ini_file:
        ini_text = expandvars(ini_file.read())
        parser.readfp(StringIO(ini_text))
    cfg = {s: dict(parser[s].items()) for s in parser.sections()}
    cfg.pop('Pool')

    agent_profile2port = {
        'trust-anchor': 8990,
        'sri': 8991,
        'pspc-org-book': 8992,
        'bc-org-book': 8993,
        'bc-registrar': 8994
    }
    cfg['Trust Anchor']['port'] = agent_profile2port['trust-anchor']
    for agent_profile in agent_profiles:
        ini = pjoin(dirname(dirname(abspath(__file__))), 'app', 'config',
                    'agent-profile', '{}.ini'.format(agent_profile))
        assert isfile(ini)
        agent_parser = ConfigParser()
        with open(ini, 'r') as ini_file:
            ini_text = expandvars(ini_file.read())
            agent_parser.readfp(StringIO(ini_text))

        cfg[agent_profile] = {
            s: dict(agent_parser[s].items())
            for s in agent_parser.sections()
        }
        cfg[agent_profile]['Agent']['port'] = agent_profile2port[agent_profile]
    print('\n\n== 0 == Test config: {}'.format(ppjson(cfg)))

    # 1. check pool & start wrappers
    if is_up(pool_ip, 9702):
        print(
            '\n\n== 1 == Using running indy pool network via docker-compose port map {}:9700 series'
            .format(pool_ip))
    else:
        set_docker()
        print(
            '\n\n== 1 == Started indy pool network via docker docker-compose port map {}:9700 series'
            .format(pool_ip))

    service_wrapper = {}
    for agent_profile in agent_profiles:
        service_wrapper[agent_profile] = Wrapper(
            agent_profile, agent_profile2port[agent_profile])
        started = service_wrapper[agent_profile].start()
        print(
            '\n\n== 2.{} == {} wrapper {}, docker-compose port-forwarded via localhost:{}'
            .format(agent_profiles.index(agent_profile),
                    'Starting' if started else 'Using running', agent_profile,
                    agent_profile2port[agent_profile]))
    atexit.register(shutdown, service_wrapper)

    # 2. ensure all demo agents (wrappers) are up
    agent_profile2did = {}
    for agent_profile in agent_profiles:
        url = url_for(agent_profile2port[agent_profile], 'did')
        # print('\n... url {}'.format(url))
        r = requests.get(url)
        # print('\n... done req\n')
        assert r.status_code == 200
        agent_profile2did[agent_profile] = r.json()
    # trust-anchor: V4SGRU86Z58d6TV7PBUe6f
    # sri: FaBAq1W5QTVDpAZtep6h19
    # bc-org-book: Rzra4McufsSNUQ1mGyWc2w
    # pspc-org-book: 45UePtKtVrZ6UycN9gmMsG
    # bc-registrar: Q4zqM7aXqm7gDQkUVLng9h
    print('\n\n== 3 == DIDs: {}'.format(ppjson(agent_profile2did)))

    S_KEY = {
        'BC': SchemaKey(agent_profile2did['bc-registrar'], 'bc-reg', '1.0'),
        'SRI-1.0': SchemaKey(agent_profile2did['sri'], 'sri', '1.0'),
        'SRI-1.1': SchemaKey(agent_profile2did['sri'], 'sri', '1.1'),
        'GREEN': SchemaKey(agent_profile2did['sri'], 'green', '1.0'),
    }
    schema_key2issuer_agent_profile = {
        S_KEY['BC']: 'bc-registrar',
        S_KEY['SRI-1.0']: 'sri',
        S_KEY['SRI-1.1']: 'sri',
        S_KEY['GREEN']: 'sri'
    }
    claim = {}

    # 3. get schemata (co-opt SCHEMA_CACHE singleton)
    i = 0
    for profile in agent_profiles:
        if 'Origin' not in cfg[profile]:
            continue
        for name in cfg[profile][
                'Origin']:  # read each schema once - each schema has one origin (agent)
            for version in (v.strip()
                            for v in cfg[profile]['Origin'][name].split(',')):
                s_key = SchemaKey(agent_profile2did[profile], name, version)
                SCHEMA_CACHE[s_key] = get_post_response(
                    agent_profile2port[profile], 'schema-lookup',
                    (agent_profile2did[profile], name, version))
                print('\n\n== 4.{} == Schema [{}]: {}'.format(
                    i, s_key, ppjson(SCHEMA_CACHE[s_key])))
                i += 1

    # 4. BC Org Book, PSPC Org Book (as HolderProvers) respond to claims-reset directive, to restore state to base line
    for profile in ('bc-org-book', 'pspc-org-book'):
        reset_resp = get_post_response(agent_profile2port[profile],
                                       'claims-reset', ())
        assert not reset_resp

    # 5. Issuers create claim-offer for HolderProvers (by proxy via Issuer) to store
    claim_offer = {}
    claim_req = {}
    i = 0
    for s_key in SCHEMA_CACHE.index().values():
        claim_offer[s_key] = get_post_response(
            agent_profile2port['bc-registrar' if s_key.origin_did ==
                               agent_profile2did['bc-registrar'] else 'sri'],
            'claim-offer-create', (*s_key, agent_profile2did[
                'bc-org-book' if s_key.origin_did ==
                agent_profile2did['bc-registrar'] else 'pspc-org-book']))
        assert claim_offer[s_key]
        print('\n\n== 5.{}.0 == Claim offer {}: {}'.format(
            i, s_key, ppjson(claim_offer[s_key])))

        claim_req[s_key] = get_post_response(
            agent_profile2port['bc-registrar' if s_key.origin_did ==
                               agent_profile2did['bc-registrar'] else 'sri'],
            'claim-offer-store', (json.dumps(claim_offer[s_key]), ),
            agent_profile2did[
                'bc-org-book' if s_key.origin_did ==
                agent_profile2did['bc-registrar'] else 'pspc-org-book'])
        assert claim_req[s_key]
        print('\n\n== 5.{}.1 == Claim request {}: {}'.format(
            i, s_key, ppjson(claim_req[s_key])))
        i += 1

    # 6. BC Registrar creates claims and stores at BC Org Book (as HolderProver)
    claim_data = {
        S_KEY['BC']: [{
            'id': 1,
            'busId': '11121398',
            'orgTypeId': 2,
            'jurisdictionId': 1,
            'legalName': 'The Original House of Pies',
            'effectiveDate': '2010-10-10',
            'endDate': None
        }, {
            'id': 2,
            'busId': '11133333',
            'orgTypeId': 1,
            'jurisdictionId': 1,
            'legalName': 'Planet Cake',
            'effectiveDate': '2011-10-01',
            'endDate': None
        }, {
            'id': 3,
            'busId': '11144444',
            'orgTypeId': 2,
            'jurisdictionId': 1,
            'legalName': 'Tart City',
            'effectiveDate': '2012-12-01',
            'endDate': None
        }],
        S_KEY['SRI-1.0']: [],
        S_KEY['SRI-1.1']: [],
        S_KEY['GREEN']: []
    }
    i = 0
    for s_key in claim_data:
        for c in claim_data[s_key]:
            claim[s_key] = get_post_response(
                agent_profile2port[schema_key2issuer_agent_profile[s_key]],
                'claim-create', (json.dumps(claim_req[s_key]), json.dumps(c)))
            assert claim[s_key]
            print('\n\n== 6.{} == BC claim: {}'.format(i,
                                                       ppjson(claim[s_key])))
            i += 1
            get_post_response(
                agent_profile2port[schema_key2issuer_agent_profile[s_key]],
                'claim-store', (json.dumps(claim[s_key]), ),
                agent_profile2did['bc-org-book'])

    # 7. SRI agent proxies to BC Org Book (as HolderProver) to find claims; actuator filters post hoc
    bc_claims_all = get_post_response(
        agent_profile2port['sri'], 'claim-request',
        (json.dumps(list_schemata([S_KEY['BC']])), json.dumps([]),
         json.dumps([]), json.dumps([])), agent_profile2did['bc-org-book'])
    print('\n\n== 7 == All BC claims, no filter: {}'.format(
        ppjson(bc_claims_all)))
    assert bc_claims_all

    bc_display_pruned_filt_post_hoc = claims_for(
        bc_claims_all['claims'],
        {S_KEY['BC']: {
             'legalName': claim_data[S_KEY['BC']][2]['legalName']
         }})
    print('\n\n== 8 == BC display claims filtered post-hoc matching {}: {}'.
          format(claim_data[S_KEY['BC']][2]['legalName'],
                 ppjson(bc_display_pruned_filt_post_hoc)))

    get_post_response(  # exercise proof restriction to one claim per attribute
        agent_profile2port['sri'], 'proof-request',
        (json.dumps(list_schemata([S_KEY['BC']])), json.dumps(
            []), json.dumps([]), json.dumps([])),
        agent_profile2did['bc-org-book'], 400)

    bc_display_pruned = prune_claims_json(
        bc_claims_all['claims'], {k
                                  for k in bc_display_pruned_filt_post_hoc})
    print('\n\n== 9 == BC claims stripped down {}'.format(
        ppjson(bc_display_pruned)))

    bc_claims_prefilt = get_post_response(
        agent_profile2port['sri'], 'claim-request',
        (json.dumps(list_schemata([S_KEY['BC']])),
         json.dumps([
             attr_match(
                 S_KEY['BC'], {
                     k: claim_data[S_KEY['BC']][2][k]
                     for k in claim_data[S_KEY['BC']][2]
                     if k in ('jurisdictionId', 'busId')
                 })
         ]), json.dumps([]), json.dumps([])), agent_profile2did['bc-org-book'])
    assert bc_claims_prefilt

    print('\n\n== 10 == BC claims filtered a priori {}'.format(
        ppjson(bc_claims_prefilt)))
    bc_display_pruned_prefilt = claims_for(bc_claims_prefilt['claims'])
    print('\n\n== 11 == BC display claims filtered a priori matching {}: {}'.
          format(claim_data[S_KEY['BC']][2]['legalName'],
                 ppjson(bc_display_pruned_prefilt)))
    assert set([*bc_display_pruned_filt_post_hoc
                ]) == set([*bc_display_pruned_prefilt])
    assert len(bc_display_pruned_filt_post_hoc) == 1

    # 8. BC Org Book (as HolderProver) creates proof and responds to request for proof (by filter)
    bc_proof_resp = get_post_response(
        agent_profile2port['sri'], 'proof-request',
        (json.dumps(list_schemata([S_KEY['BC']])),
         json.dumps([
             attr_match(
                 S_KEY['BC'], {
                     k: claim_data[S_KEY['BC']][2][k]
                     for k in claim_data[S_KEY['BC']][2]
                     if k in ('jurisdictionId', 'busId')
                 })
         ]), json.dumps([]), json.dumps([])), agent_profile2did['bc-org-book'])
    print('\n\n== 12 == BC proof (req by filter): {}'.format(
        ppjson(bc_proof_resp)))
    assert bc_proof_resp

    # 9. SRI Agent (as Verifier) verifies proof (by filter)
    bc_verification_resp = get_post_response(
        agent_profile2port['sri'], 'verification-request', (json.dumps(
            bc_proof_resp['proof-req']), json.dumps(bc_proof_resp['proof'])))

    print('\n\n== 13 == SRI agent verifies BC proof (by filter) as {}'.format(
        ppjson(bc_verification_resp)))
    assert bc_verification_resp

    # 10. BC Org Book agent (as HolderProver) creates proof (by referent)
    bc_referent = set([*bc_display_pruned_prefilt]).pop()
    s_key = set(
        schema_keys_for(bc_claims_prefilt['claims'],
                        {bc_referent}).values()).pop()  # it's unique
    bc_proof_resp = get_post_response(
        agent_profile2port['sri'], 'proof-request-by-referent',
        (json.dumps(list_schemata([s_key])), json.dumps(
            [bc_referent]), json.dumps([])), agent_profile2did['bc-org-book'])
    assert bc_proof_resp

    # 11. BC Org Book agent (as HolderProver) creates non-proof by non-referent
    get_post_response(
        agent_profile2port['sri'], 'proof-request-by-referent',
        (json.dumps(list_schemata([S_KEY['BC']])),
         json.dumps(['claim::ffffffff-ffff-ffff-ffff-ffffffffffff']),
         json.dumps([])), agent_profile2did['bc-org-book'], 400)

    # 12. SRI Agent (as Verifier) verifies proof (by referent)
    sri_bc_verification_resp = get_post_response(
        agent_profile2port['sri'], 'verification-request', (json.dumps(
            bc_proof_resp['proof-req']), json.dumps(bc_proof_resp['proof'])))
    print('\n\n== 14 == SRI agent verifies BC proof (by referent={}) as {}'.
          format(bc_referent, ppjson(sri_bc_verification_resp)))
    assert sri_bc_verification_resp

    # 13. BC Org Book agent (as HolderProver) finds claims by predicate on default attr-match, req-attrs w/schema
    claims_found_pred = get_post_response(
        agent_profile2port['sri'], 'claim-request',
        (json.dumps(list_schemata([S_KEY['BC']])), json.dumps([]),
         json.dumps([
             pred_match(S_KEY['BC'], [
                 pred_match_match('id', '>=', claim_data[S_KEY['BC']][2]['id'])
             ])
         ]), json.dumps([req_attrs(S_KEY['BC'])])),
        agent_profile2did['bc-org-book'])
    assert (set(
        req_attr['name']
        for req_attr in claims_found_pred['proof-req']['requested_attrs'].
        values()) == set(SCHEMA_CACHE[S_KEY['BC']]['data']['attr_names']) -
            {'id'})
    assert (set(req_pred['attr_name']
                for req_pred in claims_found_pred['proof-req']
                ['requested_predicates'].values()) == {'id'})

    # 14. BC Org Book agent (as HolderProver) finds claims by predicate on default attr-match and req-attrs
    claims_found_pred = get_post_response(
        agent_profile2port['sri'], 'claim-request',
        (json.dumps(list_schemata([S_KEY['BC']])), json.dumps([]),
         json.dumps([
             pred_match(S_KEY['BC'], [
                 pred_match_match('id', '>=', claim_data[S_KEY['BC']][2]['id'])
             ])
         ]), json.dumps([])), agent_profile2did['bc-org-book'])
    assert (set(
        req_attr['name']
        for req_attr in claims_found_pred['proof-req']['requested_attrs'].
        values()) == set(SCHEMA_CACHE[S_KEY['BC']]['data']['attr_names']) -
            {'id'})
    assert (set(req_pred['attr_name']
                for req_pred in claims_found_pred['proof-req']
                ['requested_predicates'].values()) == {'id'})

    print('\n\n== 15 == BC claims structure by predicate: {}'.format(
        ppjson(claims_found_pred)))
    bc_display_pred = claims_for(claims_found_pred['claims'])
    print('\n\n== 16 == BC display claims by predicate: {}'.format(
        ppjson(bc_display_pred)))
    assert len(bc_display_pred) == 1

    # 15. BC Org Book agent (as HolderProver) creates proof by predicate, default req-attrs
    bc_proof_resp_pred = get_post_response(
        agent_profile2port['sri'],
        'proof-request',
        (
            json.dumps(list_schemata([S_KEY['BC']])),
            json.dumps([]),
            json.dumps([
                pred_match(
                    S_KEY['BC'],
                    [
                        pred_match_match('id', '>=', 2),
                        pred_match_match('orgTypeId', '>=', 2),
                    ]  # resolves to one claim
                )
            ]),
            json.dumps([])),
        agent_profile2did['bc-org-book'])
    print('\n\n== 17 == BC proof by predicates id, orgTypeId >= 2: {}'.format(
        ppjson(bc_proof_resp_pred)))
    revealed = revealed_attrs(bc_proof_resp_pred['proof'])
    print(
        '\n\n== 18 == BC proof revealed attrs by predicates id, orgTypeId >= 2: {}'
        .format(ppjson(revealed)))
    assert len(revealed) == 1
    assert (set(revealed[set(revealed.keys()).pop()].keys()) == set(
        SCHEMA_CACHE[S_KEY['BC']]['data']['attr_names']) - set(
            ('id', 'orgTypeId')))

    # 16. SRI agent (as Verifier) verifies proof (by predicates)
    sri_bc_verification_resp = get_post_response(
        agent_profile2port['sri'], 'verification-request',
        (json.dumps(bc_proof_resp_pred['proof-req']),
         json.dumps(bc_proof_resp_pred['proof'])))
    print(
        '\n\n== 19 == SRI agent verifies BC proof by predicates id, orgTypeId >= 2 as {}'
        .format(ppjson(sri_bc_verification_resp)))
    assert sri_bc_verification_resp

    # 17. Create and store SRI registration completion claims, green claims from verified proof + extra data
    revealed = revealed_attrs(bc_proof_resp['proof'])[bc_referent]
    claim_data[S_KEY['SRI-1.0']].append({
        **{
            k: revealed[k]
            for k in revealed if k in SCHEMA_CACHE[S_KEY['SRI-1.0']]['data']['attr_names']
        }, 'sriRegDate': datetime.date.today().strftime('%Y-%m-%d')
    })
    claim_data[S_KEY['SRI-1.1']].append({
        **{
            k: revealed[k]
            for k in revealed if k in SCHEMA_CACHE[S_KEY['SRI-1.1']]['data']['attr_names']
        }, 'sriRegDate': datetime.date.today().strftime('%Y-%m-%d'),
        'businessLang': 'EN-CA'
    })
    claim_data[S_KEY['GREEN']].append({
        **{
            k: revealed[k]
            for k in revealed if k in SCHEMA_CACHE[S_KEY['GREEN']]['data']['attr_names']
        }, 'greenLevel':
        'Silver',
        'auditDate':
        datetime.date.today().strftime('%Y-%m-%d')
    })

    i = 0
    for s_key in claim_data:
        if s_key == S_KEY['BC']:
            continue
        for c in claim_data[s_key]:
            print('\n\n== 20.{} == Data for SRI claim on [{} v{}]: {}'.format(
                i, s_key.name, s_key.version, ppjson(c)))
            i += 1

    i = 0
    for s_key in claim_data:
        if s_key == S_KEY['BC']:
            continue
        for c in claim_data[s_key]:
            claim[s_key] = get_post_response(
                agent_profile2port[schema_key2issuer_agent_profile[s_key]],
                'claim-create', (json.dumps(claim_req[s_key]), json.dumps(c)))
            assert claim[s_key]

            print('\n\n== 21.{} == {} claim: {}'.format(
                i, s_key, ppjson(claim[s_key])))
            get_post_response(
                agent_profile2port[schema_key2issuer_agent_profile[s_key]],
                'claim-store', (json.dumps(claim[s_key]), ),
                agent_profile2did['pspc-org-book'])
            i += 1

    # 18. SRI agent proxies to PSPC Org Book agent (as HolderProver) to find all claims, one schema at a time
    i = 0
    for s_key in claim_data:
        if s_key == S_KEY['BC']:
            continue
        sri_claim = get_post_response(
            agent_profile2port['sri'], 'claim-request',
            (json.dumps(list_schemata([s_key])), json.dumps([]), json.dumps(
                []), json.dumps([])), agent_profile2did['pspc-org-book'])
        print('\n\n== 22.{}.0 == SRI claims on [{} v{}], no filter: {}'.format(
            i, s_key.name, s_key.version, ppjson(sri_claim)))
        assert len(sri_claim['claims']['attrs']) == len(
            SCHEMA_CACHE[s_key]['data']['attr_names'])

        sri_claim = get_post_response(
            agent_profile2port['sri'], 'claim-request',
            (json.dumps([]), json.dumps([attr_match(s_key)]), json.dumps(
                []), json.dumps([])), agent_profile2did['pspc-org-book'])
        print(
            '\n\n== 22.{}.1 == SRI claims, filter for all attrs in schema [{} v{}]: {}'
            .format(i, s_key.name, s_key.version, ppjson(sri_claim)))
        i += 1
        assert len(sri_claim['claims']['attrs']) == len(
            SCHEMA_CACHE[s_key]['data']['attr_names'])

    # 19. SRI agent proxies to PSPC Org Book agent (as HolderProver) to find all claims, for all schemata, on first attr
    sri_claims_all_first_attr = get_post_response(
        agent_profile2port['sri'], 'claim-request',
        (json.dumps(
            list_schemata([
                s_key for s_key in claim_data if s_key != S_KEY['BC']
            ])), json.dumps([]), json.dumps([]),
         json.dumps([
             req_attrs(s_key, [SCHEMA_CACHE[s_key]['data']['attr_names'][0]])
             for s_key in claim_data if s_key != S_KEY['BC']
         ])), agent_profile2did['pspc-org-book'])

    print('\n\n== 23 == All SRI claims at PSPC Org Book, first attr only: {}'.
          format(ppjson(sri_claims_all_first_attr)))
    assert len(sri_claims_all_first_attr['claims']['attrs']) == (
        len(SCHEMA_CACHE.index()) - 1)  # all except BC

    # 20. SRI agent proxies to PSPC Org Book agent (as HolderProver) to find all claims, on all schemata at once
    sri_claims_all = get_post_response(
        agent_profile2port['sri'], 'claim-request', (json.dumps(
            list_schemata([
                s_key for s_key in claim_data if s_key != S_KEY['BC']
            ])), json.dumps([]), json.dumps([]), json.dumps([])),
        agent_profile2did['pspc-org-book'])
    print('\n\n== 24 == All SRI claims at PSPC Org Book, all attrs: {}'.format(
        ppjson(sri_claims_all)))
    sri_display = claims_for(sri_claims_all['claims'])
    print(
        '\n\n== 25 == All SRI claims at PSPC Org Book by referent: {}'.format(
            ppjson(sri_display)))

    # 21. SRI agent proxies to PSPC Org Book agent (as HolderProver) to create (multi-claim) proof
    sri_proof_resp = get_post_response(
        agent_profile2port['sri'], 'proof-request', (json.dumps(
            list_schemata([
                s_key for s_key in claim_data if s_key != S_KEY['BC']
            ])), json.dumps([]), json.dumps([]), json.dumps([])),
        agent_profile2did['pspc-org-book'])
    print('\n\n== 26 == PSPC org book proof response on all claims: {}'.format(
        ppjson(sri_proof_resp)))
    assert len(sri_proof_resp['proof']['proof']['proofs']) == len(sri_display)

    # 22. SRI agent (as Verifier) verifies proof
    sri_verification_resp = get_post_response(
        agent_profile2port['sri'], 'verification-request', (json.dumps(
            sri_proof_resp['proof-req']), json.dumps(sri_proof_resp['proof'])))
    print(
        '\n\n== 27 == SRI agent verifies proof (by empty filter) as {}'.format(
            ppjson(sri_verification_resp)))
    assert sri_verification_resp

    # 23. SRI agent proxies to PSPC Org Book agent (as HolderProver) to create (multi-claim) proof by referent
    sri_proof_resp = get_post_response(
        agent_profile2port['sri'], 'proof-request-by-referent', (json.dumps(
            list_schemata([
                s_key for s_key in claim_data if s_key != S_KEY['BC']
            ])), json.dumps([referent
                             for referent in sri_display]), json.dumps([])),
        agent_profile2did['pspc-org-book'])
    print(
        '\n\n== 28 == PSPC org book proof response on referents {}: {}'.format(
            {referent
             for referent in sri_display}, ppjson(sri_proof_resp)))
    assert len(sri_proof_resp['proof']['proof']['proofs']) == len(sri_display)

    # 24. SRI agent (as Verifier) verifies proof
    sri_verification_resp = get_post_response(
        agent_profile2port['sri'], 'verification-request', (json.dumps(
            sri_proof_resp['proof-req']), json.dumps(sri_proof_resp['proof'])))
    print('\n\n== 29 == SRI agent verifies proof on referents {} as {}'.format(
        {referent
         for referent in sri_display}, ppjson(sri_verification_resp)))
    assert sri_verification_resp

    # 25. SRI agent proxies to PSPC Org Book agent to create multi-claim proof by ref, schemata implicit, not legalName
    sri_proof_resp = get_post_response(
        agent_profile2port['sri'], 'proof-request-by-referent',
        (json.dumps([]), json.dumps([referent for referent in sri_display]),
         json.dumps([
             req_attrs(s_key, [
                 a for a in SCHEMA_CACHE[s_key]['data']['attr_names']
                 if a != 'legalName'
             ]) for s_key in claim_data if s_key != S_KEY['BC']
         ])), agent_profile2did['pspc-org-book'])
    print(
        '\n\n== 30 == PSPC org book proof response, schemata implicit, referents {}, not legalName: {}'
        .format({referent
                 for referent in sri_display}, ppjson(sri_proof_resp)))
    assert len(sri_proof_resp['proof']['proof']['proofs']) == len(sri_display)
    revealed = revealed_attrs(sri_proof_resp['proof'])
    print('\n\n== 31 == Revealed attrs for above: {}'.format(ppjson(revealed)))
    assert Counter([attr for c in revealed
                    for attr in revealed[c]]) == Counter([
                        attr for s_key in SCHEMA_CACHE.index().values()
                        if s_key != S_KEY['BC']
                        for attr in SCHEMA_CACHE[s_key]['data']['attr_names']
                        if attr != 'legalName'
                    ])

    # 26. SRI agent (as Verifier) verifies proof
    sri_verification_resp = get_post_response(
        agent_profile2port['sri'], 'verification-request', (json.dumps(
            sri_proof_resp['proof-req']), json.dumps(sri_proof_resp['proof'])))
    print('\n\n== 32 == SRI agent verifies proof on referents {} as {}'.format(
        {referent
         for referent in sri_display}, ppjson(sri_verification_resp)))
    assert sri_verification_resp

    # 27. SRI agent proxies to PSPC Org Book agent (as HolderProver) to create proof on req-attrs for green schema attrs
    sri_proof_resp = get_post_response(
        agent_profile2port['sri'], 'proof-request',
        (json.dumps([]), json.dumps([]), json.dumps(
            []), json.dumps([req_attrs(S_KEY['GREEN'])])),
        agent_profile2did['pspc-org-book'])
    print(
        '\n\n== 33 == PSPC org book proof to green claims response: {}'.format(
            ppjson(sri_proof_resp)))
    assert {
        sri_proof_resp['proof-req']['requested_attrs'][k]['name']
        for k in sri_proof_resp['proof-req']['requested_attrs']
    } == set(SCHEMA_CACHE[S_KEY['GREEN']]['data']['attr_names'])

    # 28. SRI agent (as Verifier) verifies proof
    sri_verification_resp = get_post_response(
        agent_profile2port['sri'], 'verification-request', (json.dumps(
            sri_proof_resp['proof-req']), json.dumps(sri_proof_resp['proof'])))
    print(
        '\n\n== 34 == SRI agent verifies proof on [{} v{}] attrs as {}'.format(
            S_KEY['GREEN'].name, S_KEY['GREEN'].version,
            ppjson(sri_verification_resp)))
    assert sri_verification_resp

    # 29. SRI agent proxies to non-agent
    x_resp = get_post_response(agent_profile2port['sri'], 'claim-def-send',
                               (*S_KEY['SRI-1.0'], ), 'XXXXXXXXXXXXXXXXXXXXXX',
                               400)
    print('\n\n== 35 == Bogus proxy response: {}'.format(ppjson(x_resp)))

    # 30. Exercise helper GET TXN call
    seq_no = {k
              for k in SCHEMA_CACHE.index().keys()
              }.pop()  # there will be a real transaction here
    url = url_for(agent_profile2port['sri'], 'txn/{}'.format(seq_no))
    r = requests.get(url)
    assert r.status_code == 200
    assert r.json()
    print('\n\n== 36 == ledger transaction #{}: {}'.format(
        seq_no, ppjson(r.json())))

    # 31. txn# non-existence case
    url = url_for(agent_profile2port['sri'], 'txn/99999')
    r = requests.get(url)  # ought not exist
    assert r.status_code == 200
    print('\n\n== 37 == txn #99999: {}'.format(ppjson(r.json())))
    assert not r.json()

    # XX. Shut down service wrappers for next test
    shutdown(service_wrapper)
async def test_wrapper(pool_ip):
    agent_profiles = ['trust-anchor', 'sri', 'pspc-org-book', 'bc-org-book', 'bc-registrar']

    # 0. configure
    cfg = {}
    parser = ConfigParser()
    ini = pjoin(dirname(dirname(abspath(__file__))), 'config', 'config.ini')
    assert isfile(ini)
    parser.read(ini)
    cfg = {s: dict(parser[s].items()) for s in parser.sections()}

    for agent_profile in agent_profiles:
        ini = pjoin(dirname(dirname(abspath(__file__))), 'config', 'agent-profile', '{}.ini'.format(agent_profile))
        assert isfile(ini)
        agent_parser = ConfigParser()
        agent_parser.read(ini)

        cfg[agent_profile] = {s: dict(agent_parser[s].items()) for s in agent_parser.sections()}

    print('\n\n== 0 == Test config: {}'.format(ppjson(cfg)))

    # 1. check docker & start wrappers
    if is_up(pool_ip, 9702):
        print('\n\n== 1 == Using running indy pool network at {}'.format(pool_ip))
    else:
        set_docker()
        print('\n\n== 1 == Started indy pool network via docker at {}'.format(pool_ip))
    service_wrapper = {}
    for agent_profile in agent_profiles:
        service_wrapper[agent_profile] = Wrapper(agent_profile, cfg[agent_profile]['Agent'])
        started = service_wrapper[agent_profile].start()
        print('\n\n== 2.{} == {} wrapper: {}'.format(
            agent_profiles.index(agent_profile),
            'started' if started else 'using running',
            agent_profile))
    atexit.register(shutdown, service_wrapper)

    # 2. ensure all demo agents (wrappers) are up
    did = {}
    for agent_profile in agent_profiles:
        url = url_for(cfg[agent_profile]['Agent'], 'did')
        r = requests.get(url)
        assert r.status_code == 200
        did[agent_profile] = r.json()
    # trust-anchor: V4SGRU86Z58d6TV7PBUe6f
    # sri: FaBAq1W5QTVDpAZtep6h19
    # bc-org-book: Rzra4McufsSNUQ1mGyWc2w
    # pspc-org-book: 45UePtKtVrZ6UycN9gmMsG
    # bc-registrar: Q4zqM7aXqm7gDQkUVLng9h
    print('\n\n== 3 == DIDs: {}'.format(ppjson(did)))

    # 3. get schema
    schema_lookup_json = form_json(
        'schema-lookup',
        (
            did['trust-anchor'],
            cfg['Schema']['name'],
            cfg['Schema']['version']
        ))
    url = url_for(cfg['Trust Anchor'], 'schema-lookup')
    r = requests.post(url, json=json.loads(schema_lookup_json))
    assert r.status_code == 200
    schema = r.json()

    # 4. BC Org Book, PSPC Org Book (as HolderProvers) respond to claims-reset directive, to restore state to base line
    claims_reset_json = form_json(
        'claims-reset',
        ())
    for profile in ('bc-org-book', 'pspc-org-book'):
        url = url_for(cfg[profile]['Agent'], 'claims-reset')
        r = requests.post(url, json=json.loads(claims_reset_json))
        assert r.status_code == 200
        reset_resp = r.json()
        assert not reset_resp

    # 5. BC Registrar (as Issuer) sends claim-hello, then creates claims and stores at BC Org Book (as HolderProver)
    claim_hello_json = form_json('claim-hello', (did['bc-registrar'],), did['bc-org-book'])
    url = url_for(cfg['bc-registrar']['Agent'], 'claim-hello')
    r = requests.post(url, json=json.loads(claim_hello_json))
    assert r.status_code == 200
    claim_req = r.json()
    assert claim_req

    claims = [
        {
            'id': 1,
            'busId': 11121398,
            'orgTypeId': 2,
            'jurisdictionId': 1,
            'LegalName': 'The Original House of Pies',
            'effectiveDate': '2010-10-10',
            'endDate': None,
            'sriRegDate': None
        },
        {
            'id': 2,
            'busId': 11133333,
            'orgTypeId': 1,
            'jurisdictionId': 1,
            'LegalName': 'Planet Cake',
            'effectiveDate': '2011-10-01',
            'endDate': None,
            'sriRegDate': None
        },
        {
            'id': 3,
            'busId': 11144444,
            'orgTypeId': 2,
            'jurisdictionId': 1,
            'LegalName': 'Tart City',
            'effectiveDate': '2012-12-01',
            'endDate': None,
            'sriRegDate': None
        }
    ]
    for c in claims:
        claim_create_json = form_json('claim-create', (json.dumps(claim_req), json.dumps(c)))
        url = url_for(cfg['bc-registrar']['Agent'], 'claim-create')
        r = requests.post(url, json=json.loads(claim_create_json))
        assert r.status_code == 200
        claim = r.json()
        assert claim

        print('\n\n== 4 == claim: {}'.format(ppjson(claim)))
        claim_store_json = form_json(
            'claim-store',
            (json.dumps(claim),),
            did['bc-org-book'])
        url = url_for(cfg['bc-registrar']['Agent'], 'claim-store')
        r = requests.post(url, json=json.loads(claim_store_json))
        assert r.status_code == 200
        # response is empty

    # 6. BC Org Book (as HolderProver) finds claims
    claim_req_all_json = form_json('claim-request', (json.dumps({}),), did['bc-org-book'])
    url = url_for(cfg['sri']['Agent'], 'claim-request')
    r = requests.post(url, json=json.loads(claim_req_all_json))
    assert r.status_code == 200
    claims_all = r.json()
    assert claims_all
    print('\n\n== 5 == claims by attr, no filter, api-post {}'.format(ppjson(claims_all)))

    display_pruned_postfilt = claims_for(claims_all['claims'], {'LegalName': claims[2]['LegalName']})
    print('\n\n== 6 == display claims filtered post-hoc matching {}: {}'.format(
        claims[2]['LegalName'],
        ppjson(display_pruned_postfilt)))
    display_pruned = prune_claims_json({k for k in display_pruned_postfilt}, claims_all['claims'])
    print('\n\n== 7 == stripped down {}'.format(ppjson(display_pruned)))

    claim_req_prefilt_json = form_json(
        'claim-request',
        (json.dumps({k: claims[2][k] for k in claims[2] if k in ('sriRegDate', 'busId')}),),
        did['bc-org-book'])
    url = url_for(cfg['sri']['Agent'], 'claim-request')
    r = requests.post(url, json=json.loads(claim_req_prefilt_json))
    assert r.status_code == 200
    claims_prefilt = r.json()
    assert claims_prefilt

    print('\n== 8 == claims by attr, with filter a priori {}'.format(ppjson(claims_prefilt)))
    display_pruned_prefilt = claims_for(claims_prefilt['claims'])
    print('\n== 9 == display claims filtered a priori matching {}: {}'.format(
        claims[2]['LegalName'],
        ppjson(display_pruned_prefilt)))
    assert set([*display_pruned_postfilt]) == set([*display_pruned_prefilt])
    assert len(display_pruned_postfilt) == 1

    # 7. BC Org Book (as HolderProver) creates proof and responds to request for proof (by filter)
    claim_uuid = set([*display_pruned_prefilt]).pop()
    proof_req_json = form_json(
        'proof-request',
        (json.dumps({k: claims[2][k] for k in claims[2] if k in ('sriRegDate', 'busId')}),),
        did['bc-org-book'])
    url = url_for(cfg['sri']['Agent'], 'proof-request')
    r = requests.post(url, json=json.loads(proof_req_json))
    assert r.status_code == 200
    proof_resp = r.json()
    assert proof_resp

    # 8. SRI Agent (as Verifier) verifies proof (by filter)
    verification_req_json = form_json(
        'verification-request',
        (json.dumps(proof_resp['proof-req']),json.dumps(proof_resp['proof'])))
    url = url_for(cfg['sri']['Agent'], 'verification-request')
    r = requests.post(url, json=json.loads(verification_req_json))
    assert r.status_code == 200
    verification_resp = r.json()
    print('\n== 10 == the proof (by filter) verifies as {}'.format(ppjson(verification_resp)))
    assert verification_resp

    # 9. BC Org Book (as HolderProver) creates proof and responds to request for proof (by claim-uuid)
    proof_req_json_by_uuid = form_json('proof-request-by-claim-uuid', (json.dumps(claim_uuid),), did['bc-org-book'])
    url = url_for(cfg['sri']['Agent'], 'proof-request-by-claim-uuid')
    r = requests.post(url, json=json.loads(proof_req_json_by_uuid))
    assert r.status_code == 200
    proof_resp = r.json()
    assert proof_resp

    proof_req_json_by_non_uuid = form_json(
        'proof-request-by-claim-uuid',
        (json.dumps('claim::ffffffff-ffff-ffff-ffff-ffffffffffff'),),
        did['bc-org-book'])
    url = url_for(cfg['sri']['Agent'], 'proof-request-by-claim-uuid')
    r = requests.post(url, json=json.loads(proof_req_json_by_non_uuid))
    assert r.status_code == 500

    # 10. SRI Agent (as Verifier) verifies proof (by uuid)
    verification_req_json = form_json(
        'verification-request',
        (json.dumps(proof_resp['proof-req']), json.dumps(proof_resp['proof'])))
    url = url_for(cfg['sri']['Agent'], 'verification-request')
    r = requests.post(url, json=json.loads(verification_req_json))
    assert r.status_code == 200
    verification_resp = r.json()
    print('\n== 11 == the proof (by claim-uuid={}) verifies as {}'.format(claim_uuid, ppjson(verification_resp)))
    assert verification_resp

    # 11. SRI agent (as Issuer) creates SRI reg completion claim from proof, stores at PSPC Org Book (as HolderProver)
    sri_claim_hello_json = form_json('claim-hello', (did['sri'],), did['pspc-org-book'])
    url = url_for(cfg['sri']['Agent'], 'claim-hello')
    r = requests.post(url, json=json.loads(sri_claim_hello_json))
    assert r.status_code == 200
    sri_claim_req = r.json()
    assert sri_claim_req

    sri_claim = revealed_attrs(proof_resp['proof'])
    yyyy_mm_dd = datetime.date.today().strftime('%Y-%m-%d')
    sri_claim['sriRegDate'] = yyyy_mm_dd

    sri_claim_create_json = form_json('claim-create', (json.dumps(sri_claim_req), json.dumps(sri_claim)))
    url = url_for(cfg['sri']['Agent'], 'claim-create')
    r = requests.post(url, json=json.loads(sri_claim_create_json))
    assert r.status_code == 200
    sri_claim = r.json()
    assert sri_claim

    sri_claim_store_json = form_json('claim-store', (json.dumps(sri_claim),), did['pspc-org-book'])
    url = url_for(cfg['sri']['Agent'], 'claim-store')
    r = requests.post(url, json=json.loads(sri_claim_store_json))
    assert r.status_code == 200
    # response is empty

    # 12. PSPC Org Book (as HolderProver) finds claims
    sri_claim_req_all_json = form_json('claim-request', (json.dumps({}),), did['pspc-org-book'])
    url = url_for(cfg['sri']['Agent'], 'claim-request')
    r = requests.post(url, json=json.loads(sri_claim_req_all_json))
    assert r.status_code == 200
    sri_claims_all = r.json()
    print('\n== 12 == SRI claims-all: {}'.format(ppjson(sri_claims_all)))
    assert sri_claims_all

    # 13. PSPC Org Book (as HolderProver) creates proof (by claim-uuid)
    sri_display = claims_for(sri_claims_all['claims'])
    assert len(sri_display) == 1
    sri_claim_uuid = set([*sri_display]).pop()
    sri_proof_req_json_by_uuid = form_json(
        'proof-request-by-claim-uuid',
        (json.dumps(sri_claim_uuid),),
        did['pspc-org-book'])
    url = url_for(cfg['sri']['Agent'], 'proof-request-by-claim-uuid')
    r = requests.post(url, json=json.loads(sri_proof_req_json_by_uuid))
    assert r.status_code == 200
    sri_proof_resp = r.json()
    assert sri_proof_resp

    # 14. SRI (as Verifier) verifies proof (by uuid)
    sri_verification_req_json = form_json(
        'verification-request',
        (json.dumps(sri_proof_resp['proof-req']), json.dumps(sri_proof_resp['proof'])))
    url = url_for(cfg['sri']['Agent'], 'verification-request')
    r = requests.post(url, json=json.loads(sri_verification_req_json))
    assert r.status_code == 200
    sri_verification_resp = r.json()
    print('\n== 13 == the SRI proof (by claim-uuid={}) verifies as {}'.format(
        sri_claim_uuid,
        ppjson(sri_verification_resp)))
    assert sri_verification_resp

    # 15. Exercise helper GET TXN call
    url = url_for(cfg['sri']['Agent'], 'txn/{}'.format(schema['seqNo']))
    r = requests.get(url)
    assert r.status_code == 200
    assert r.json()
    print('\n== 14 == ledger transaction by seq no {}: {}'.format(schema['seqNo'], ppjson(r.json())))
    
    # 16. txn# non-existence case
    url = url_for(cfg['sri']['Agent'], 'txn/99999')
    r = requests.get(url)  # ought not exist
    assert r.status_code == 200
    print('\n== 15 == txn #99999: {}'.format(ppjson(r.json())))
    assert not r.json() 
Exemple #4
0
async def test_agents_process_forms_local(pool_name, pool_genesis_txn_path,
                                          seed_trustee1, pool_genesis_txn_file,
                                          path_home):

    # 1. Open pool, init agents
    async with NodePool(
            pool_name, pool_genesis_txn_path) as p, (TrustAnchorAgent(
                p, seed_trustee1, 'trustee_wallet', None, '127.0.0.1', '8000',
                'api/v0')) as tag, (SRIAgent(
                    p, 'SRI-Agent-0000000000000000000000', 'sri-agent-wallet',
                    None, '127.0.0.1', 8001, 'api/v0')) as sag, (OrgBookAgent(
                        p, 'PSPC-Org-Book-Agent-000000000000',
                        'pspc-org-book-agent-wallet', None, '127.0.0.1', 8003,
                        'api/v0')) as pspcobag, (OrgBookAgent(
                            p, 'BC-Org-Book-Agent-00000000000000',
                            'bc-org-book-agent-wallet', None, '127.0.0.1',
                            8003, 'api/v0')) as bcobag, (BCRegistrarAgent(
                                p, 'BC-Registrar-Agent-0000000000000',
                                'bc-reg-agent-wallet', None, '127.0.0.1', 8004,
                                'api/v0')) as bcrag:

        assert p.handle is not None

        # 2. Publish agent particulars to ledger if not yet present
        for ag in (tag, sag, pspcobag, bcobag, bcrag):
            nym_lookup_form = {
                'type': 'agent-nym-lookup',
                'data': {
                    'agent-nym': {
                        'did': ag.did
                    }
                }
            }
            nym = json.loads(await ag.process_post(nym_lookup_form))
            if not nym:
                resp_json = await tag.process_post({
                    'type': 'agent-nym-send',
                    'data': {
                        'agent-nym': {
                            'did': ag.did,
                            'verkey': ag.verkey
                        }
                    }
                })

            nym = json.loads(await ag.process_post(nym_lookup_form))
            assert nym

            endpoint_lookup_form = {
                'type': 'agent-endpoint-lookup',
                'data': {
                    'agent-endpoint': {
                        'did': ag.did
                    }
                }
            }
            endpoint = json.loads(await tag.process_post(endpoint_lookup_form))
            if not endpoint:
                resp_json = await ag.process_post({
                    'type': 'agent-endpoint-send',
                    'data': {}
                })
            endpoint = json.loads(await ag.process_post(endpoint_lookup_form))
            assert endpoint

        try:  # Make sure only a trust anchor can register an agent
            await sag.process_post({
                'type': 'agent-nym-send',
                'data': {
                    'agent-nym': {
                        'did': sag.did,
                        'verkey': sag.verkey
                    }
                }
            })
            assert False
        except NotImplementedError:
            pass

        # 3. Publish schema to ledger if not yet present; get from ledger
        schema_data = {
            'name':
            'supplier-registration',
            'version':
            '1.1',
            'attr_names': [
                'id', 'busId', 'orgTypeId', 'jurisdictionId', 'LegalName',
                'effectiveDate', 'endDate', 'sriRegDate'
            ]
        }

        schema_lookup_form = {
            'type': 'schema-lookup',
            'data': {
                'schema': {
                    'issuer-did': tag.did,
                    'name': schema_data['name'],
                    'version': 'xxxx'
                },
            }
        }

        try:
            schema_json = await tag.process_post(schema_lookup_form
                                                 )  # Bad version number
            assert False
        except IndyError:
            pass

        schema_lookup_form['data']['schema']['version'] = '999.999'
        assert not json.loads(
            await tag.process_post(schema_lookup_form))  # ought not exist
        schema_lookup_form['data']['schema']['version'] = '1.1'
        schema_json = await tag.process_post(schema_lookup_form)  # may exist
        if not json.loads(schema_json):
            schema_send = json.loads(await tag.process_post({
                'type': 'schema-send',
                'data': {
                    'schema': {
                        'issuer-did': tag.did,
                        'name': schema_data['name'],
                        'version': schema_data['version']
                    },
                    'attr-names': schema_data['attr_names']
                }
            }))
            assert schema_send
        schema_json = await tag.process_post(schema_lookup_form)
        schema = json.loads(schema_json)  # should exist now
        assert schema
        print('\n\n== 2 == SCHEMA {}'.format(ppjson(schema)))

        try:  # Make sure only an origin can send a schema
            await sag.process_post({
                'type': 'schema-send',
                'data': {
                    'schema': {
                        'issuer-did': tag.did,
                        'name': schema_data['name'],
                        'version': schema_data['version']
                    },
                    'attr-names': schema_data['attr_names']
                }
            })
            assert False
        except NotImplementedError:
            pass

        # 4. BC Registrar and SRI agents (as Issuers) create, store,  and publish claim def to ledger
        # print('TAG DID {}'.format(tag.did))            # V4SG...
        # print('SAG DID {}'.format(sag.did))            # FaBA...
        # print('PSPCOBAG DID {}'.format(pspcobag.did))  # 45Ue...
        # print('BCOBAG DID {}'.format(bcobag.did))      # Rzra...
        # print('BCRAG DID {}'.format(bcrag.did))        # Q4zq...

        claim_def_send_form = {'type': 'claim-def-send', 'data': {}}

        try:  # schema unspecified, ought to fail
            await bcrag.process_post(claim_def_send_form)
        except ValueError:
            pass

        await bcrag.process_post(schema_lookup_form
                                 )  # seed Issuers' schema caches
        await sag.process_post(schema_lookup_form)

        await bcrag.process_post(claim_def_send_form)
        await sag.process_post(claim_def_send_form)
        claim_def_json = await bcobag.get_claim_def(
            schema['seqNo'], bcrag.did)  # ought to exist now (short-circuit)
        assert json.loads(claim_def_json)['ref'] == schema['seqNo']

        # 5. Setup master secrets, claim reqs at HolderProver agents
        master_secret_set_form = {
            'type': 'master-secret-set',
            'data': {
                'label': 'maestro'
            }
        }
        claim_hello_form = {
            'type': 'claim-hello',
            'data': {
                'issuer-did': bcrag.did
            }
        }

        try:  # master secret unspecified, ought to fail
            await bcobag.process_post(claim_hello_form)
        except ValueError:
            pass

        await bcobag.process_post(master_secret_set_form)

        try:  # schema unspecified, ought to fail
            claim_req_json = await bcobag.process_post(claim_hello_form)
        except ValueError:
            pass

        claims_reset_form = {'type': 'claims-reset', 'data': {}}
        claims_reset_resp = json.loads(await
                                       bcobag.process_post(claims_reset_form))
        assert not claims_reset_resp  # make sure later ops are OK on reset wallet -- response is {} if OK

        await bcobag.process_post(schema_lookup_form
                                  )  # seed HolderProver's schema cache
        claim_req_json = await bcobag.process_post(claim_hello_form)
        claim_req = json.loads(claim_req_json)
        assert claim_req

        # 6. BC Reg agent (as Issuer) issues claims and stores at HolderProver: get claim req, create claim, store claim
        claims = [{
            'id': 1,
            'busId': 11121398,
            'orgTypeId': 2,
            'jurisdictionId': 1,
            'LegalName': 'The Original House of Pies',
            'effectiveDate': '2010-10-10',
            'endDate': None,
            'sriRegDate': None
        }, {
            'id': 2,
            'busId': 11133333,
            'orgTypeId': 1,
            'jurisdictionId': 1,
            'LegalName': 'Planet Cake',
            'effectiveDate': '2011-10-01',
            'endDate': None,
            'sriRegDate': None
        }, {
            'id': 3,
            'busId': 11144444,
            'orgTypeId': 2,
            'jurisdictionId': 1,
            'LegalName': 'Tart City',
            'effectiveDate': '2012-12-01',
            'endDate': None,
            'sriRegDate': None
        }]
        for c in claims:
            claim_json = await bcrag.process_post({
                'type': 'claim-create',
                'data': {
                    'claim-req': claim_req,
                    'claim-attrs': c
                }
            })
            await bcobag.process_post({
                'type': 'claim-store',
                'data': {
                    'claim': json.loads(claim_json)
                }
            })

        # 7. BC Org Book agent (as HolderProver) finds claims
        by_attr = {
            'nonce': '1234',
            'name': 'proof_req_0',
            'version': '0',
            'requested_attrs': {
                '{}_uuid'.format(attr): {
                    'schema_seq_no': schema['seqNo'],
                    'name': attr
                }
                for attr in claims[0]
            },
            'requested_predicates': {},
        }
        claims_all = json.loads(await bcobag.process_post({
            'type': 'claim-request',
            'data': {
                'claim-filter': {
                    'attr-match': {},
                    'predicate-match': []
                }
            }
        }))
        print('\n\n== 3 == claims by attr, no filter, process-post {}'.format(
            ppjson(claims_all)))
        display_pruned_postfilt = claims_for(
            claims_all['claims'], {'LegalName': claims[2]['LegalName']})
        print('\n\n== 4 == display claims filtered post-hoc matching {}: {}'.
              format(claims[2]['LegalName'], ppjson(display_pruned_postfilt)))
        display_pruned = prune_claims_json(
            {k
             for k in display_pruned_postfilt}, claims_all['claims'])
        print('\n\n== 5 == stripped down {}'.format(ppjson(display_pruned)))

        claims_prefilt_json = await bcobag.process_post({
            'type': 'claim-request',
            'data': {
                'claim-filter': {
                    'attr-match': {
                        k: claims[2][k]
                        for k in claims[2] if k in ('sriRegDate', 'busId')
                    },
                    'predicate-match': []
                }
            }
        })
        claims_prefilt = json.loads(claims_prefilt_json)
        print(
            '\n\n== 6 == claims by attr, with filter a priori, process-post {}'
            .format(ppjson(claims_prefilt)))
        display_pruned_prefilt = claims_for(claims_prefilt['claims'])
        print('\n\n== 7 == display claims filtered a priori matching {}: {}'.
              format(claims[2]['LegalName'], ppjson(display_pruned_prefilt)))
        assert set([*display_pruned_postfilt
                    ]) == set([*display_pruned_prefilt])
        assert len(display_pruned_postfilt) == 1

        # 8. BC Org Book (as HolderProver) creates proof (by filter)
        proof_resp = json.loads(await bcobag.process_post({
            'type': 'proof-request',
            'data': {
                'claim-filter': {
                    'attr-match': {
                        k: claims[2][k]
                        for k in claims[2] if k in ('sriRegDate', 'busId')
                    },
                    'predicate-match': []
                }
            }
        }))
        print('\n\n== 8 == proof response (by filter) {}'.format(
            ppjson(proof_resp)))

        # 9. SRI agent (as Verifier) verifies proof (by filter)
        rc_json = await sag.process_post({
            'type': 'verification-request',
            'data': proof_resp
        })
        print('\n\n== 9 == the proof (by filter) verifies as {}'.format(
            ppjson(rc_json)))
        assert json.loads(rc_json)

        # 10. BC Org Book (as HolderProver) creates proof (by claim-uuid)
        claim_uuid = set([*display_pruned_prefilt]).pop()
        proof_resp = json.loads(await bcobag.process_post({
            'type': 'proof-request-by-claim-uuid',
            'data': {
                'claim-uuid': claim_uuid
            }
        }))
        print('\n\n== 10 == proof response by claim-uuid={}: {}'.format(
            claim_uuid, ppjson(proof_resp)))

        # 11. BC Org Book (HolderProver) creates non-proof (by non-claim-uuid)
        non_claim_uuid = 'claim::ffffffff-ffff-ffff-ffff-ffffffffffff'
        try:
            proof_resp = json.loads(await bcobag.process_post({
                'type': 'proof-request-by-claim-uuid',
                'data': {
                    'claim-uuid': non_claim_uuid
                }
            }))
        except ValueError:
            pass

        # 12. SRI agent (as Verifier) verifies proof (by claim-uuid)
        rc_json = await sag.process_post({
            'type': 'verification-request',
            'data': proof_resp
        })
        print('\n\n== 12 == the proof by claim_uuid={} verifies as {}'.format(
            claim_uuid, ppjson(rc_json)))
        assert json.loads(rc_json)

        # 13. Finish bootstrapping PSPC Org Book as HolderProver
        master_secret_set_form['data']['label'] = 'shhhh'
        await pspcobag.process_post(master_secret_set_form)
        await pspcobag.process_post(schema_lookup_form)  # seed schema cache
        sri_claims_reset_resp = json.loads(
            await pspcobag.process_post(claims_reset_form))
        assert not sri_claims_reset_resp  # make sure later ops are OK on reset wallet -- response is {} if OK

        sri_claim_def_json = await bcobag.get_claim_def(
            schema['seqNo'], sag.did)
        assert json.loads(sri_claim_def_json)['ref'] == schema['seqNo']
        await sag.process_post(schema_lookup_form)  # seed schema cache

        # 14. Create and store SRI registration completion claim from verified proof
        claim_hello_form['data']['issuer-did'] = sag.did
        sri_claim_req_json = await pspcobag.process_post(claim_hello_form)
        sri_claim_req = json.loads(sri_claim_req_json)
        assert sri_claim_req

        sri_claim = revealed_attrs(proof_resp['proof'])
        yyyy_mm_dd = datetime.date.today().strftime('%Y-%m-%d')
        sri_claim['sriRegDate'] = yyyy_mm_dd
        print('\n\n== 13 == sri_claim: {}'.format(ppjson(sri_claim)))

        sri_claim_json = await sag.process_post({
            'type': 'claim-create',
            'data': {
                'claim-req': sri_claim_req,
                'claim-attrs': sri_claim
            }
        })
        await pspcobag.process_post({
            'type': 'claim-store',
            'data': {
                'claim': json.loads(sri_claim_json)
            }
        })
        assert json.loads(sri_claim_json)

        # 15. PSPC Org Book (as HolderProver) finds claim
        sri_claims_all = json.loads(await pspcobag.process_post({
            'type': 'claim-request',
            'data': {
                'claim-filter': {
                    'attr-match': {},
                    'predicate-match': []
                }
            }
        }))
        print('\n\n== 14 == SRI claim {}'.format(ppjson(sri_claims_all)))

        # 16. PSPC Org Book (as HolderProver) creates proof
        sri_display = claims_for(sri_claims_all['claims'])
        sri_claim_uuid = set([*sri_display]).pop()
        sri_proof_resp = json.loads(await pspcobag.process_post({
            'type': 'proof-request-by-claim-uuid',
            'data': {
                'claim-uuid': sri_claim_uuid
            }
        }))
        print('\n\n== 15 == SRI proof response by claim-uuid={}: {}'.format(
            sri_claim_uuid, ppjson(sri_proof_resp)))

        # 17. SRI (as Verifier) verifies proof
        rc_json = await sag.process_post({
            'type': 'verification-request',
            'data': sri_proof_resp
        })
        print('\n\n== 16 == the SRI proof by claim_uuid={} verifies as {}'.
              format(sri_claim_uuid, ppjson(rc_json)))
        assert json.loads(rc_json)

        # 18. Exercise helper GET calls
        txn_json = await sag.process_get_txn(schema['seqNo'])
        print('\n\n== 17 == schema by txn #{}: {}'.format(
            schema['seqNo'], ppjson(txn_json)))
        assert json.loads(txn_json)
        txn_json = await sag.process_get_txn(99999)  # ought not exist
        assert not json.loads(txn_json)

        did_json = await bcrag.process_get_did()
        print('\n\n== 18 == bcrag did: {}'.format(ppjson(did_json)))
        assert json.loads(did_json)
Exemple #5
0
async def test_agents_direct(pool_name, pool_genesis_txn_path, seed_trustee1,
                             pool_genesis_txn_file, path_home):

    # 1. Open pool, init agents
    p = NodePool(pool_name, pool_genesis_txn_path)
    await p.open()
    assert p.handle

    tag = TrustAnchorAgent(p, seed_trustee1, 'trustee_wallet', None,
                           '127.0.0.1', 8000, 'api/v0')
    sag = SRIAgent(p, 'SRI-Agent-0000000000000000000000', 'sri-agent-wallet',
                   None, '127.0.0.1', 8001, 'api/v0')
    pspcobag = OrgBookAgent(p, 'PSPC-Org-Book-Agent-000000000000',
                            'pspc-org-book-agent-wallet', None, '127.0.0.1',
                            8002, 'api/v0')
    bcobag = OrgBookAgent(p, 'BC-Org-Book-Agent-00000000000000',
                          'bc-org-book-agent-wallet', None, '127.0.0.1', 8003,
                          'api/v0')
    bcrag = BCRegistrarAgent(p, 'BC-Registrar-Agent-0000000000000',
                             'bc-registrar-agent-wallet', None, '127.0.0.1',
                             8004, 'api/v0')

    await tag.open()
    await sag.open()
    await pspcobag.open()
    await bcobag.open()
    await bcrag.open()

    # 2. Publish agent particulars to ledger if not yet present
    for ag in (tag, sag, pspcobag, bcobag, bcrag):
        if not json.loads(await tag.get_nym(ag.did)):
            await tag.send_nym(ag.did, ag.verkey)
        if not json.loads(await tag.get_endpoint(ag.did)):
            await ag.send_endpoint()

    nyms = {
        'tag': await tag.get_nym(tag.did),
        'sag': await tag.get_nym(sag.did),
        'pspcobag': await tag.get_nym(pspcobag.did),
        'bcobag': await tag.get_nym(bcobag.did),
        'bcrag': await tag.get_nym(bcrag.did)
    }
    endpoints = {
        'tag': await tag.get_endpoint(tag.did),
        'sag': await tag.get_endpoint(sag.did),
        'pspcobag': await tag.get_endpoint(pspcobag.did),
        'bcobag': await tag.get_endpoint(bcobag.did),
        'bcrag': await tag.get_endpoint(bcrag.did)
    }

    print('\n\n== 1 == nyms {}\nendpoints {}\n'.format(nyms, endpoints))

    for k in nyms:
        assert 'dest' in nyms[k]
    for k in endpoints:
        assert 'host' in endpoints[k]
        assert 'port' in endpoints[k]

    # 3. Publish schema to ledger if not yet present; get from ledger
    schema_data = {
        'name':
        'supplier-registration',
        'version':
        '1.1',
        'attr_names': [
            'id', 'busId', 'orgTypeId', 'jurisdictionId', 'LegalName',
            'effectiveDate', 'endDate', 'sriRegDate'
        ]
    }

    try:
        schema_json = await tag.get_schema(tag.did, 'Xxxx',
                                           'X.x')  # Bad version number
    except IndyError as e:
        assert ErrorCode.LedgerInvalidTransaction == e.error_code
    schema_json = await tag.get_schema(tag.did, schema_data['name'],
                                       schema_data['version'])  # may exist
    if not json.loads(schema_json):
        schema_json = await tag.send_schema(json.dumps(schema_data))
    schema_json = await tag.get_schema(tag.did, schema_data['name'],
                                       schema_data['version']
                                       )  # should exist now
    schema = json.loads(schema_json)
    assert schema
    print('\n\n== 2 == SCHEMA {}'.format(ppjson(schema)))

    # 4. BC Registrar and SRI agents (as Issuers) create, store, and publish claim definitions to ledger
    # print('TAG DID {}'.format(tag.did))            # V4SG...
    # print('SAG DID {}'.format(sag.did))            # FaBA...
    # print('PSPCOBAG DID {}'.format(pspcobag.did))  # 45Ue...
    # print('BCOBAG DID {}'.format(bcobag.did))      # Rzra...
    # print('BCRAG DID {}'.format(bcrag.did))        # Q4zq...
    non_claim_def_json = await bcobag.get_claim_def(999999, bcrag.did
                                                    )  # ought not exist
    assert not json.loads(non_claim_def_json)

    claim_def_json = await bcrag.send_claim_def(schema_json)
    claim_def_json = await bcobag.get_claim_def(schema['seqNo'], bcrag.did
                                                )  # ought to exist now

    await sag.get_schema(tag.did, schema_data['name'],
                         schema_data['version'])  # seed schema cache
    sri_claim_def_json = await sag.send_claim_def(schema_json)
    sri_claim_def_json = await pspcobag.get_claim_def(schema['seqNo'], sag.did)

    assert json.loads(claim_def_json)['ref'] == schema['seqNo']
    assert json.loads(sri_claim_def_json)['ref'] == schema['seqNo']

    print('\n\n== 3 == claim def {}'.format(ppjson(
        json.loads(claim_def_json))))

    # 5. Setup master secrets, claim reqs at HolderProver agents
    await bcobag.create_master_secret('MasterSecret')
    await pspcobag.create_master_secret('SecretMaster')

    for ag in (bcobag, pspcobag):
        wallet_num = ag.wallet.num
        assert (await ag.reset_wallet()
                ) > wallet_num  # makes sure later ops are OK on reset wallet

    await bcobag.store_claim_offer(bcrag.did, schema['seqNo'])
    await pspcobag.store_claim_offer(sag.did, schema['seqNo'])
    claim_req_json = await bcobag.store_claim_req(bcrag.did, claim_def_json)
    sri_claim_req_json = await pspcobag.store_claim_req(
        sag.did, sri_claim_def_json)

    print('\n\n== 4 == BC reg claim req {}\n\nSRI claim req {}'.format(
        claim_req_json, sri_claim_req_json))

    # 6. BC Reg agent (as Issuer) issues claims and stores at HolderProver: get claim req, create claim, store claim
    claims = [{
        'id': claim_value_pair('1'),
        'busId': claim_value_pair('11121398'),
        'orgTypeId': claim_value_pair('2'),
        'jurisdictionId': claim_value_pair('1'),
        'LegalName': claim_value_pair('The Original House of Pies'),
        'effectiveDate': claim_value_pair('2010-10-10'),
        'endDate': claim_value_pair(None),
        'sriRegDate': claim_value_pair(None)
    }, {
        'id': claim_value_pair('2'),
        'busId': claim_value_pair('11133333'),
        'orgTypeId': claim_value_pair('1'),
        'jurisdictionId': claim_value_pair('1'),
        'LegalName': claim_value_pair('Planet Cake'),
        'effectiveDate': claim_value_pair('2011-10-01'),
        'endDate': claim_value_pair(None),
        'sriRegDate': claim_value_pair(None)
    }, {
        'id': claim_value_pair('3'),
        'busId': claim_value_pair('11144444'),
        'orgTypeId': claim_value_pair('2'),
        'jurisdictionId': claim_value_pair('1'),
        'LegalName': claim_value_pair('Tart City'),
        'effectiveDate': claim_value_pair('2012-12-01'),
        'endDate': claim_value_pair(None),
        'sriRegDate': claim_value_pair(None)
    }]
    for c in claims:
        (_, claim_json) = await bcrag.create_claim(claim_req_json, c)
        assert json.loads(claim_json)
        await bcobag.store_claim(claim_json)

    # 7. BC Org Book agent (as HolderProver) finds claims
    by_attr = {
        'nonce': '1234',
        'name': 'proof_req_0',
        'version': '0',
        'requested_attrs': {
            '{}_uuid'.format(attr): {
                'schema_seq_no': schema['seqNo'],
                'name': attr
            }
            for attr in claims[0]
        },
        'requested_predicates': {}
    }
    (claim_uuids_all,
     claims_found_json) = await bcobag.get_claims(json.dumps(by_attr))
    print('\n\n== 5 == claims by attr, no filter {}; {}'.format(
        claim_uuids_all, ppjson(claims_found_json)))
    claims_found = json.loads(claims_found_json)
    display_pruned_postfilt = claims_for(
        claims_found, {'LegalName': claims[2]['LegalName'][0]})
    print(
        '\n\n== 6 == display claims filtered post-hoc matching {}: {}'.format(
            claims[2]['LegalName'][0], ppjson(display_pruned_postfilt)))
    display_pruned = prune_claims_json({k
                                        for k in display_pruned_postfilt},
                                       claims_found)
    print('\n\n== 7 == stripped down {}'.format(ppjson(display_pruned)))

    filter_enc = {
        k: claims[2][k][0]
        for k in claims[2] if k in ('sriRegDate', 'busId')
    }
    (claim_uuids_filt,
     claims_found_json) = await bcobag.get_claims(json.dumps(by_attr),
                                                  filter_enc)
    print('\n\n== 8 == claims by attr, filtered a priori {}; {}'.format(
        claim_uuids_filt, ppjson(claims_found_json)))
    assert set([*display_pruned_postfilt]) == claim_uuids_filt
    assert len(display_pruned_postfilt) == 1

    claim_uuid = claim_uuids_filt.pop()

    # 8. BC Org Book (as HolderProver) creates proof for claim specified by filter
    claims_found = json.loads(claims_found_json)
    requested_claims = {
        'self_attested_attributes': {},
        'requested_attrs': {
            attr: [claim_uuid, True]
            for attr in by_attr['requested_attrs']
            if attr in claims_found['attrs']
        },
        'requested_predicates':
        {pred: claim_uuid
         for pred in by_attr['requested_predicates']}
    }
    proof_json = await bcobag.create_proof(json.dumps(by_attr), schema,
                                           json.loads(claim_def_json),
                                           requested_claims)
    print('\n\n== 9 == proof (by filter) {}'.format(ppjson(proof_json)))

    # 9. SRI agent (as Verifier) verifies proof (by filter)
    rc_json = await sag.verify_proof(json.dumps(by_attr),
                                     json.loads(proof_json), schema,
                                     json.loads(claim_def_json))
    print('\n\n== 10 == the proof (by filter) verifies as {}'.format(
        ppjson(rc_json)))
    assert json.loads(rc_json)

    # 10. BC Org Book (as HolderProver) finds claim by claim-uuid, no claim by non-claim-uuid
    claim_found_by_uuid = json.loads(await bcobag.get_claim_by_claim_uuid(
        schema_json, claim_uuid))
    print('\n\n== 11 == claim by claim-uuid={}: {}'.format(
        claim_uuid, ppjson(claim_found_by_uuid)))
    assert claim_found_by_uuid
    assert claim_found_by_uuid['attrs']

    non_claim_by_uuid = json.loads(await bcobag.get_claim_by_claim_uuid(
        schema_json, 'claim::ffffffff-ffff-ffff-ffff-ffffffffffff'))
    assert non_claim_by_uuid
    print('\n\n== 12 == non-claim: {}'.format(ppjson(non_claim_by_uuid)))
    assert all(not non_claim_by_uuid['attrs'][attr]
               for attr in non_claim_by_uuid['attrs'])

    # 11. BC Org Book (as HolderProver) creates proof for claim specified by claim-uuid
    requested_claims = {
        'self_attested_attributes': {},
        'requested_attrs':
        {attr: [claim_uuid, True]
         for attr in claim_found_by_uuid['attrs']},
        'requested_predicates': {}
    }
    proof_json = await bcobag.create_proof(json.dumps(by_attr), schema,
                                           json.loads(claim_def_json),
                                           requested_claims)
    proof = json.loads(proof_json)
    print('\n\n== 13 == proof by claim-uuid={} {}'.format(
        claim_uuid, ppjson(proof_json)))

    # 12. SRI agent (as Verifier) verifies proof
    rc_json = await sag.verify_proof(json.dumps(by_attr), proof, schema,
                                     json.loads(claim_def_json))
    print('\n\n== 14 == the proof by claim-uuid={} verifies as {}'.format(
        claim_uuid, ppjson(rc_json)))
    assert json.loads(rc_json)

    # 13. Create and store SRI registration completion claim from verified proof
    sri_claim = revealed_attrs(proof)
    yyyy_mm_dd = datetime.date.today().strftime('%Y-%m-%d')
    sri_claim['sriRegDate'] = claim_value_pair(yyyy_mm_dd)
    print('\n\n== 15 == sri_claim: {}'.format(ppjson(sri_claim)))
    (_, sri_claim_json) = await sag.create_claim(sri_claim_req_json, c)
    assert json.loads(sri_claim_json)
    await pspcobag.store_claim(sri_claim_json)

    # 14. PSPC Org Book Agent (as HolderProver) finds claim
    (sri_claim_uuids_all,
     sri_claims_found_json) = await pspcobag.get_claims(json.dumps(by_attr))
    print('\n\n== 16 == SRI claims by attr, no filter {}; {}'.format(
        sri_claim_uuids_all, ppjson(sri_claims_found_json)))
    assert len(sri_claim_uuids_all) == 1
    sri_claim_uuid = sri_claim_uuids_all.pop()
    sri_claims_found = json.loads(sri_claims_found_json)

    # 15. PSPC Org Book Agent (as HolderProver) creates proof
    sri_requested_claims = {
        'self_attested_attributes': {},
        'requested_attrs':
        {attr: [sri_claim_uuid, True]
         for attr in sri_claims_found['attrs']},
        'requested_predicates': {}
    }
    sri_proof_json = await pspcobag.create_proof(
        json.dumps(by_attr), schema, json.loads(sri_claim_def_json),
        sri_requested_claims)
    print('\n\n== 17 == PSPC Org Book proof on claim-uuid={} {}'.format(
        sri_claim_uuid, ppjson(sri_proof_json)))

    # 16. SRI (as Verifier) verify proof
    rc_json = await sag.verify_proof(json.dumps(by_attr),
                                     json.loads(sri_proof_json), schema,
                                     json.loads(sri_claim_def_json))
    print('\n\n== 18 == the SRI proof by claim-uuid={} verifies as {}'.format(
        sri_claim_uuid, ppjson(rc_json)))
    assert json.loads(rc_json)

    await bcrag.close()
    await bcobag.close()
    await pspcobag.close()
    await sag.close()
    await tag.close()
    await p.close()