Skip to content

Commit 0723910

Browse files
committed
Basics to version-bump aca-py
* Bumped aca-py version to 0.6 in Dockerfile * add auto-provision param to aries basic args * add auto-provision param to aries advanced args Adjust proof controller to reflect version 0.6 API of aca-py. * Added sending problem report function * Tidied up th ecode to reflect Python linting * Tidied up function definitions in order to reflect swagger docs order Bump version of aca-py for attachment protocol example * Change aca-py version for Docker image * add --auto-provision flag to aca-py start so it runs properly and a new wallet is created on startup Changes to plugin routes to work with v0.6.0 * Connection takes now a session instead of context * session is now a context property (context.session()) * context now comes from AdminRequestContext (new import) and is the request["context"] * Outbound_handler now directly takes the router from request and not app.request * ConnectionRecord has changed to ConnRecord (this takes the session) Add mediation controller * Added all async functions to cover mediation via API * minor fixes to proofs.py, fixed naming of parsed args Removed superfluous variable parsing in mediation.py Make changes to remove by topic method call without the dirty changes to the notebook like cell runs Add reference to mediation manual/README for usage Pave the way for multitenant use * supply apropriate params in configuration YAML files so the containers start up with multitenent use enabled * The required and supplied password is password as a dummy. DO NOT use this in production. * Add a new MultitenancyController that exposes the entire swagger API. Remove auto-provision param from docker-compose file. This is passed from the configuration YAML. Addresses merge request feedback. * remove multitenancy from args file and ** Move them to a new config YAML file for multitenancy * auto-provision param remains in args file as it is required to produce the previously known behaviour from before v0.6 Remove duplicate auto-provion flag from docker-compose.yml Remove multitenant args file * This will be handled by parsing startup args like described [here](https://github.com/hyperledger/aries-cloudagent-python/blob/b8f28dfe1b8b84f1fd5143bd5219c93b0913c3cc/aries_cloudagent/config/argparse.py)
1 parent b62dcb4 commit 0723910

File tree

10 files changed

+216
-35
lines changed

10 files changed

+216
-35
lines changed

configuration/aries-args-advanced.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ seed: !ENV ${WALLET_SEED}
4545

4646

4747
auto-accept-requests: true
48+
auto-provision: true
4849
auto-respond-credential-proposal: true
4950
auto-respond-credential-offer: true
5051
auto-respond-credential-request: true

configuration/aries-args-basic.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ wallet-type: !ENV ${WALLET_TYPE}
3333
wallet-name: !ENV ${WALLET_NAME}
3434
wallet-key: !ENV ${WALLET_KEY}
3535
seed: !ENV ${WALLET_SEED}
36+
auto-provision: true
37+
3638

3739
## run a local postgres (docker) like:
3840
## docker run --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword -d -p 5432:5432 postgres:10

dockerfiles/agents/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM bcgovimages/aries-cloudagent:py36-1.15-0_0.5.6
1+
FROM bcgovimages/aries-cloudagent:py36-1.15-1_0.6.0
22

33
ADD configuration ./configuration
44
ADD scripts ./scripts

dockerfiles/agents/Dockerfile.attachmentprotocol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM bcgovimages/aries-cloudagent:py36-1.15-0_0.5.6
1+
FROM bcgovimages/aries-cloudagent:py36-1.15-1_0.6.0
22

33
ADD configuration ./configuration
44
ADD scripts ./scripts

libs/acapy-protocol-example/acapy_protocol_example/protocolexample/v1_0/routes.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55

66
from marshmallow import fields, Schema
77

8-
from aries_cloudagent.connections.models.connection_record import ConnectionRecord
8+
from aries_cloudagent.connections.models.conn_record import ConnRecord
99
from aries_cloudagent.messaging.valid import UUIDFour
1010
from aries_cloudagent.storage.error import StorageNotFoundError
11+
from aries_cloudagent.admin.request_context import AdminRequestContext
1112

1213
from .messages.protocolexample import ProtocolExample
1314

@@ -42,15 +43,17 @@ async def connections_send_ping(request: web.BaseRequest):
4243
request: aiohttp request object
4344
4445
"""
45-
context = request.app["request_context"]
46+
context: AdminRequestContext = request["context"]
4647
connection_id = request.match_info["conn_id"]
47-
outbound_handler = request.app["outbound_message_router"]
48+
outbound_handler = request["outbound_message_router"]
49+
session = await context.session()
50+
4851
body = await request.json()
4952
example = body.get("example")
5053
response_requested = body.get("response_requested")
5154

5255
try:
53-
connection = await ConnectionRecord.retrieve_by_id(context, connection_id)
56+
connection = await ConnRecord.retrieve_by_id(session, connection_id)
5457
except StorageNotFoundError:
5558
raise web.HTTPNotFound()
5659

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# For usage please consult https://github.com/hyperledger/aries-cloudagent-python/blob/main/Mediation.md
2+
3+
from .base import BaseController
4+
from aiohttp import ClientSession
5+
import logging
6+
from typing import List
7+
8+
logger = logging.getLogger("aries_controller.mediation")
9+
10+
11+
class MediationController(BaseController):
12+
13+
def __init__(self, admin_url: str, client_session: ClientSession):
14+
super().__init__(admin_url, client_session)
15+
self.base_url = "/mediation"
16+
17+
def default_handler(self, payload):
18+
logger.debug("Mediation Message received", payload)
19+
20+
21+
# Get default mediator
22+
async def get_default_mediator(self):
23+
return await self.admin_POST(f"{self.base_url}/default-mediator")
24+
25+
26+
# Clear default mediator
27+
async def delete_default_mediator(self):
28+
return await self.admin_DELETE(f"{self.base_url}/default-mediator")
29+
30+
31+
# Retrieve keylists by connection or role
32+
async def get_keylists(self, conn_id: str = None, role: str = None):
33+
params = {}
34+
if conn_id:
35+
params["conn_id"] = conn_id
36+
if role:
37+
params["role"] = role
38+
39+
return await self.admin_GET(f"{self.base_url}/keylists", params=params)
40+
41+
42+
# Send keylist query to mediator
43+
async def send_keylist_query(self, request, mediation_id: str, paginate_limit: int = -1, paginate_offset: int = 0):
44+
params = {}
45+
params["mediation_id"] = mediation_id
46+
if paginate_limit:
47+
params["paginate_limit"] = paginate_limit
48+
if paginate_offset:
49+
params["paginate_offset"] = paginate_offset
50+
51+
return await self.admin_POST(f"{self.base_url}/keylists/{mediation_id}/send-keylist-query", params=params, json_data=request)
52+
53+
54+
# Send keylist update to mediator
55+
async def send_keylist_update(self, request, mediation_id: str):
56+
return await self.admin_POST(f"{self.base_url}/keylists/{mediation_id}/send-keylist-update", json_data=request)
57+
58+
59+
# Request mediation from connection
60+
async def request_mediation(self, request, conn_id: str):
61+
return await self.admin_POST(f"{self.base_url}/request/{conn_id}", json_data=request)
62+
63+
64+
# Query mediation requests, returns list of all mediation records
65+
async def get_mediation_records(self, mediator_terms: [str], recipient_terms: [str], state: str = None, conn_id: str = None):
66+
params = {}
67+
if conn_id:
68+
params["conn_id"] = conn_id
69+
if mediator_terms:
70+
params["mediator_terms"] = mediator_terms
71+
if recipient_terms:
72+
params["recipient_terms"] = recipient_terms
73+
if state:
74+
params["state"] = state
75+
76+
return await self.admin_GET(f"{self.base_url}/requests", params=params)
77+
78+
79+
# Retrieve mediation request record
80+
async def get_mediation_record_by_id(self, mediation_id: str):
81+
return await self.admin_GET(f"{self.base_url}/requests/{mediation_id}")
82+
83+
84+
# Delete mediation request record
85+
async def delete_mediation_record_by_id(self, mediation_id: str):
86+
return await self.admin_DELETE(f"{self.base_url}/requests/{mediation_id}")
87+
88+
89+
# Deny a stored mediation request
90+
async def deny_mediation_request_by_id(self, request, mediation_id: str):
91+
return await self.admin_POST(f"{self.base_url}/requests/{mediation_id}/deny", json_data=request)
92+
93+
94+
# Grant received mediation request
95+
async def grant_mediation_request_by_id(self, mediation_id: str):
96+
return await self.admin_POST(f"{self.base_url}/requests/{mediation_id}/grant")
97+
98+
99+
# Grant received mediation request
100+
async def set_default_mediator(self, mediation_id: str):
101+
return await self.admin_PUT(f"{self.base_url}/requests/{mediation_id}/default-mediator")
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# For usage please consult https://github.com/hyperledger/aries-cloudagent-python/blob/main/Mediation.md
2+
3+
from .base import BaseController
4+
from aiohttp import ClientSession
5+
import logging
6+
from typing import List
7+
8+
logger = logging.getLogger("aries_controller.multitenancy")
9+
10+
11+
class MultitenancyController(BaseController):
12+
13+
def __init__(self, admin_url: str, client_session: ClientSession):
14+
super().__init__(admin_url, client_session)
15+
self.base_url = "/multitenancy"
16+
17+
def default_handler(self, payload):
18+
logger.debug("Multitenancy Message received", payload)
19+
20+
21+
# Create a subwallet
22+
async def create_subwallet(self, request):
23+
return await self.admin_POST(f"{self.base_url}/wallet", json_data=request)
24+
25+
26+
# Get a single subwallet
27+
async def get_single_subwallet_by_id(self, wallet_id: str):
28+
return await self.admin_GET(f"{self.base_url}/wallet/{wallet_id}")
29+
30+
31+
# Update a subwallet
32+
async def update_subwallet_by_id(self, request, wallet_id: str):
33+
return await self.admin_PUT(f"{self.base_url}/wallet/{wallet_id}", json_data=request)
34+
35+
36+
# Remove a subwallet
37+
async def remove_subwallet_by_id(self, request, wallet_id: str):
38+
return await self.admin_POST(f"{self.base_url}/wallet/{wallet_id}/remove", json_data=request)
39+
40+
41+
# Get auth token for a subwallet
42+
async def get_subwallet_authtoken_by_id(self, request, wallet_id: str):
43+
return await self.admin_POST(f"{self.base_url}/wallet/{wallet_id}/token", json_data=request)
44+
45+
46+
# Query subwallets
47+
async def query_subwallets(self, wallet_name: str = None):
48+
params = {}
49+
if wallet_name:
50+
params["wallet_name"] = wallet_name
51+
52+
return await self.admin_GET(f"{self.base_url}/wallets")
53+
54+
55+

libs/aries-basic-controller/aries_basic_controller/controllers/proof.py

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,15 @@ def __init__(self, admin_url: str, client_session: ClientSession):
1616
def default_handler(self, payload):
1717
logger.debug("Present Proof Message received", payload)
1818

19+
20+
# Creates a presentation request not bound to any proposal or existing connection
21+
async def create_request(self, request):
22+
# TODO How should proof request object be broken up? Complex.
23+
# Do we want user to have to know how to build this object?
24+
return await self.admin_POST(f"{self.base_url}/create-request", json_data=request)
25+
26+
27+
# Fetch all present-proof exchange records
1928
async def get_records(self, connection_id: str = None, thread_id: str = None, state: str = None, role: str = None):
2029
params = {}
2130
if connection_id:
@@ -29,10 +38,18 @@ async def get_records(self, connection_id: str = None, thread_id: str = None, st
2938

3039
return await self.admin_GET(f"{self.base_url}/records", params=params)
3140

41+
42+
# Fetch a single presentation exchange record
3243
async def get_record_by_id(self, pres_ex_id):
3344
return await self.admin_GET(f"{self.base_url}/records/{pres_ex_id}")
45+
3446

35-
# Fetch a single presentation exchange record
47+
# Remove an existing presentation exchange record
48+
async def remove_presentation_record(self, pres_ex_id):
49+
return await self.admin_DELETE(f"{self.base_url}/records/{pres_ex_id}")
50+
51+
52+
# Fetch credentials for a presentation request from wallet
3653
async def get_presentation_credentials(self, pres_ex_id, count: int = None, wql_query: str = None, start: int = None, referent: str = None):
3754
params = {}
3855
if count:
@@ -47,39 +64,37 @@ async def get_presentation_credentials(self, pres_ex_id, count: int = None, wql_
4764
params["referent"] = referent
4865

4966
return await self.admin_GET(f"{self.base_url}/records/{pres_ex_id}/credentials", params=params)
67+
5068

51-
# Sends a presentation proposal
52-
async def send_proposal(self, proposal):
53-
54-
return await self.admin_POST(f"{self.base_url}/send-proposal", json_data=proposal)
55-
56-
# Creates a presentation request not bound to any proposal or existing connection
57-
async def create_request(self, request):
58-
# TODO How should proof request object be broken up? Complex.
59-
# Do we want user to have to know how to build this object?
60-
61-
return await self.admin_POST(f"{self.base_url}/create-request", json_data=request)
62-
63-
64-
# Sends a free presentation request not bound to any proposal
65-
async def send_request(self, request):
66-
return await self.admin_POST(f"{self.base_url}/send-request", json_data=request)
69+
# Send a problem report for presentation exchange
70+
async def send_problem_report(self, request, pres_ex_id):
71+
return await self.admin_POST(f"{self.base_url}/records/{pres_ex_id}/problem-report", json_data=request)
6772

68-
async def send_request_for_proposal(self, pres_ex_id, proposal_request):
6973

70-
return await self.admin_POST(f"{self.base_url}/records/{pres_ex_id}/send-request", json_data=proposal_request)
74+
# Sends a proof presentation
75+
async def send_presentation(self, request, pres_ex_id):
76+
return await self.admin_POST(f"{self.base_url}/records/{pres_ex_id}/send-presentation", json_data=request)
7177

72-
# Send a proof presentation
73-
async def send_presentation(self, pres_ex_id, presentation):
7478

75-
return await self.admin_POST(f"{self.base_url}/records/{pres_ex_id}/send-presentation", json_data=presentation)
79+
# Sends a presentation request in reference to a proposal
80+
async def send_request_for_proposal(self, request, pres_ex_id):
81+
return await self.admin_POST(f"{self.base_url}/records/{pres_ex_id}/send-request", json_data=request)
7682

83+
7784
# Verify a received presentation
7885
async def verify_presentation(self, pres_ex_id):
7986
return await self.admin_POST(f"{self.base_url}/records/{pres_ex_id}/verify-presentation")
8087

81-
async def remove_presentation_record(self, pres_ex_id):
82-
return await self.admin_DELETE(f"{self.base_url}/records/{pres_ex_id}")
8388

89+
# Sends a presentation proposal
90+
async def send_proposal(self, request):
91+
return await self.admin_POST(f"{self.base_url}/send-proposal", json_data=request)
92+
93+
94+
# Sends a free presentation request not bound to any proposal
95+
async def send_request(self, request):
96+
return await self.admin_POST(f"{self.base_url}/send-request", json_data=request)
97+
98+
8499
# def build_proof_request(self, name, version, requested_attributes, requested_predicates):
85100

libs/attachment-protocol/attach_protocol/attachment_protocol/v1_0/routes.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
from marshmallow import fields, Schema
44
from aiohttp import web, FormData
55
from aiohttp_apispec import docs, match_info_schema, form_schema, request_schema, response_schema
6-
from aries_cloudagent.connections.models.connection_record import ConnectionRecord
6+
from aries_cloudagent.connections.models.conn_record import ConnRecord
77
from aries_cloudagent.messaging.valid import UUIDFour
88
from aries_cloudagent.storage.error import StorageNotFoundError
9+
from aries_cloudagent.storage.base import BaseStorage
10+
from aries_cloudagent.admin.request_context import AdminRequestContext
911

1012
from .messages.attachment import Attachment, AttachmentSchema
1113

@@ -32,9 +34,11 @@ async def send_attachment(request: web.BaseRequest):
3234
"""
3335
Request Handler to send attachment protocol
3436
"""
35-
context = request.app["request_context"]
37+
context: AdminRequestContext = request["context"]
3638
connection_id = request.match_info["conn_id"]
37-
outbound_handler = request.app["outbound_message_router"]
39+
outbound_handler = request["outbound_message_router"]
40+
41+
session = await context.session()
3842

3943
# WARNING: don't do that if you plan to receive large files!
4044
# TODO change to handle large files??
@@ -58,7 +62,7 @@ async def send_attachment(request: web.BaseRequest):
5862
content = file.read()
5963

6064
try:
61-
connection = await ConnectionRecord.retrieve_by_id(context, connection_id)
65+
connection = await ConnRecord.retrieve_by_id(session, connection_id)
6266
except StorageNotFoundError:
6367
raise web.HTTPNotFound()
6468

tutorials/aries-basic-controller/notebooks/alice/Part 2 - Aries Basic Controller.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@
302302
"outputs": [],
303303
"source": [
304304
"topic = \"basicmessages\"\n",
305-
"agent_controller.remove_all(topic)\n",
305+
"agent_controller.remove_all_listeners(topic)\n",
306306
"\n"
307307
]
308308
},

0 commit comments

Comments
 (0)