Skip to content

Commit

Permalink
Add anoncreds profile basic scenario test (openwallet-foundation#3232)
Browse files Browse the repository at this point in the history
Signed-off-by: Jamie Hale <jamiehalebc@gmail.com>
  • Loading branch information
jamshale authored and ff137 committed Oct 22, 2024
1 parent ca8cc0a commit e75516b
Show file tree
Hide file tree
Showing 2 changed files with 276 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
services:
alice:
image: acapy-test
ports:
- "3001:3001"
command: >
start
--label Alice
--inbound-transport http 0.0.0.0 3000
--outbound-transport http
--endpoint http://alice:3000
--admin 0.0.0.0 3001
--admin-insecure-mode
--tails-server-base-url http://tails:6543
--genesis-url http://test.bcovrin.vonx.io/genesis
--wallet-type askar-anoncreds
--wallet-name alice
--wallet-key insecure
--auto-provision
--log-level info
--debug-webhooks
--notify-revocation
healthcheck:
test: curl -s -o /dev/null -w '%{http_code}' "http://localhost:3001/status/live" | grep "200" > /dev/null
start_period: 30s
interval: 7s
timeout: 5s
retries: 5
depends_on:
tails:
condition: service_started

bob:
image: acapy-test
ports:
- "3002:3001"
command: >
start
--label Bob
--inbound-transport http 0.0.0.0 3000
--outbound-transport http
--endpoint http://bob:3000
--admin 0.0.0.0 3001
--admin-insecure-mode
--tails-server-base-url http://tails:6543
--genesis-url http://test.bcovrin.vonx.io/genesis
--wallet-type askar-anoncreds
--wallet-name bob
--wallet-key insecure
--auto-provision
--log-level info
--debug-webhooks
--monitor-revocation-notification
healthcheck:
test: curl -s -o /dev/null -w '%{http_code}' "http://localhost:3001/status/live" | grep "200" > /dev/null
start_period: 30s
interval: 7s
timeout: 5s
retries: 5

example:
container_name: controller
build:
context: ../..
environment:
- ALICE=http://alice:3001
- BOB=http://bob:3001
volumes:
- ./example.py:/usr/src/app/example.py:ro,z
command: python -m example
depends_on:
alice:
condition: service_healthy
bob:
condition: service_healthy

tails:
image: ghcr.io/bcgov/tails-server:latest
ports:
- 6543:6543
environment:
- GENESIS_URL=http://test.bcovrin.vonx.io/genesis
command: >
tails-server
--host 0.0.0.0
--port 6543
--storage-path /tmp/tails-files
--log-level INFO
187 changes: 187 additions & 0 deletions scenarios/examples/anoncreds_issuance_and_revocation/example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
"""Minimal reproducible example script.
This script is for you to use to reproduce a bug or demonstrate a feature.
"""

import asyncio
import json
from dataclasses import dataclass
from os import getenv
from secrets import token_hex

from acapy_controller import Controller
from acapy_controller.controller import Minimal
from acapy_controller.logging import logging_to_stdout
from acapy_controller.models import V20PresExRecord, V20PresExRecordList
from acapy_controller.protocols import (
DIDResult,
didexchange,
indy_issue_credential_v2,
indy_present_proof_v2,
params,
)
from aiohttp import ClientSession

ALICE = getenv("ALICE", "http://alice:3001")
BOB = getenv("BOB", "http://bob:3001")


def summary(presentation: V20PresExRecord) -> str:
"""Summarize a presentation exchange record."""
request = presentation.pres_request
return "Summary: " + json.dumps(
{
"state": presentation.state,
"verified": presentation.verified,
"presentation_request": request.dict(by_alias=True) if request else None,
},
indent=2,
sort_keys=True,
)


@dataclass
class SchemaResult(Minimal):
"""Schema result."""

schema_state: dict


@dataclass
class CredDefResult(Minimal):
"""Credential definition result."""

credential_definition_state: dict


async def main():
"""Test Controller protocols."""
async with Controller(base_url=ALICE) as alice, Controller(base_url=BOB) as bob:
# Connecting
alice_conn, bob_conn = await didexchange(alice, bob)

# Issuance prep
config = (await alice.get("/status/config"))["config"]
genesis_url = config.get("ledger.genesis_url")
public_did = (await alice.get("/wallet/did/public", response=DIDResult)).result
if not public_did:
public_did = (
await alice.post(
"/wallet/did/create",
json={"method": "sov", "options": {"key_type": "ed25519"}},
response=DIDResult,
)
).result
assert public_did

async with ClientSession() as session:
register_url = genesis_url.replace("/genesis", "/register")
async with session.post(
register_url,
json={
"did": public_did.did,
"verkey": public_did.verkey,
"alias": None,
"role": "ENDORSER",
},
) as resp:
assert resp.ok

await alice.post("/wallet/did/public", params=params(did=public_did.did))

schema = await alice.post(
"/anoncreds/schema",
json={
"schema": {
"name": "anoncreds-test-" + token_hex(8),
"version": "1.0",
"attrNames": ["firstname", "lastname"],
"issuerId": public_did.did,
}
},
response=SchemaResult,
)
cred_def = await alice.post(
"/anoncreds/credential-definition",
json={
"credential_definition": {
"issuerId": schema.schema_state["schema"]["issuerId"],
"schemaId": schema.schema_state["schema_id"],
"tag": token_hex(8),
},
"options": {
"revocation_registry_size": 2000,
"support_revocation": True,
},
},
response=CredDefResult,
)

# Issue a credential
alice_cred_ex, _ = await indy_issue_credential_v2(
alice,
bob,
alice_conn.connection_id,
bob_conn.connection_id,
cred_def.credential_definition_state["credential_definition_id"],
{"firstname": "Bob", "lastname": "Builder"},
)

# Present the the credential's attributes
await indy_present_proof_v2(
bob,
alice,
bob_conn.connection_id,
alice_conn.connection_id,
requested_attributes=[{"name": "firstname"}],
)

# Revoke credential
await alice.post(
url="/anoncreds/revocation/revoke",
json={
"connection_id": alice_conn.connection_id,
"rev_reg_id": alice_cred_ex.indy.rev_reg_id,
"cred_rev_id": alice_cred_ex.indy.cred_rev_id,
"publish": True,
"notify": True,
"notify_version": "v1_0",
},
)

await bob.record(topic="revocation-notification")

# Request proof, no interval
await indy_present_proof_v2(
bob,
alice,
bob_conn.connection_id,
alice_conn.connection_id,
requested_attributes=[
{
"name": "firstname",
"restrictions": [
{
"cred_def_id": cred_def.credential_definition_state[
"credential_definition_id"
]
}
],
}
],
)

# Query presentations
presentations = await alice.get(
"/present-proof-2.0/records",
response=V20PresExRecordList,
)

# Presentation summary
for i, pres in enumerate(presentations.results):
print(summary(pres))


if __name__ == "__main__":
logging_to_stdout()
asyncio.run(main())

0 comments on commit e75516b

Please sign in to comment.