diff --git a/askar_tools/README.md b/askar_tools/README.md index 8ffb8e3..18c5651 100644 --- a/askar_tools/README.md +++ b/askar_tools/README.md @@ -49,8 +49,9 @@ poetry install ### Import Wallet: - * Imports a wallet from a database location into a multi-tenant multi-wallet admin and database location. - +- Imports a wallet from a database location into a multi-tenant multi-wallet admin and database location. +- **Important:** Existing connections to the imported agent won't work without a proxy server routing the requests to the correct agent. This is because any external agents will still only know the old endpoint. +- The database will not be deleted from the source location. - `tenant-import` (Import a wallet into a multi-wallet multi-tenant agent): ``` diff --git a/askar_tools/__main__.py b/askar_tools/__main__.py index 810d677..23e2276 100644 --- a/askar_tools/__main__.py +++ b/askar_tools/__main__.py @@ -4,14 +4,14 @@ import asyncio import logging import sys -from typing import Optional from urllib.parse import urlparse -from .exporter import Exporter -from .multi_wallet_converter import MultiWalletConverter -from .pg_connection import PgConnection -from .sqlite_connection import SqliteConnection -from .tenant_importer import TenantImporter +from askar_tools.error import InvalidArgumentsError +from askar_tools.exporter import Exporter +from askar_tools.multi_wallet_converter import MultiWalletConverter +from askar_tools.pg_connection import PgConnection +from askar_tools.sqlite_connection import SqliteConnection +from askar_tools.tenant_importer import TenantImporter, TenantImportObject def config(): @@ -57,6 +57,7 @@ def config(): "--wallet-key-derivation-method", type=str, help=("Specify key derivation method for the wallet. Default is 'ARGON2I_MOD'."), + default="ARGON2I_MOD", ) # Export @@ -101,6 +102,7 @@ def config(): help=( "Specify key derivation method for the tenant wallet. Default is 'ARGON2I_MOD'." ), + default="ARGON2I_MOD", ) parser.add_argument( "--tenant-wallet-type", @@ -109,6 +111,7 @@ def config(): """Specify the wallet type of the tenant wallet. Either 'askar' or 'askar-anoncreds'. Default is 'askar'.""" ), + default="askar", ) parser.add_argument( "--tenant-label", @@ -134,80 +137,61 @@ def config(): "--tenant-dispatch-type", type=str, help=("Specify the dispatch type for the tenant wallet."), + default="base", ) args, _ = parser.parse_known_args(sys.argv[1:]) - if args.strategy == "tenant-import": - if ( - not args.tenant_uri - or not args.tenant_wallet_name - or not args.tenant_wallet_key - ): - parser.error( - """For tenant-import strategy, tenant-uri, tenant-wallet-name, and - tenant-wallet-key are required.""" - ) + if args.strategy == "tenant-import" and ( + not args.tenant_uri or not args.tenant_wallet_name or not args.tenant_wallet_key + ): + parser.error( + """For tenant-import strategy, tenant-uri, tenant-wallet-name, and + tenant-wallet-key are required.""" + ) return args -async def main( - strategy: str, - uri: str, - wallet_name: Optional[str] = None, - wallet_key: Optional[str] = None, - wallet_key_derivation_method: Optional[str] = "ARGON2I_MOD", - multitenant_sub_wallet_name: Optional[str] = "multitenant_sub_wallet", - tenant_uri: Optional[str] = None, - tenant_wallet_name: Optional[str] = None, - tenant_wallet_key: Optional[str] = None, - tenant_wallet_type: Optional[str] = "askar", - tenant_wallet_key_derivation_method: Optional[str] = "ARGON2I_MOD", - tenant_label: Optional[str] = None, - tenant_image_url: Optional[str] = None, - tenant_webhook_urls: Optional[list] = None, - tenant_extra_settings: Optional[dict] = None, - tenant_dispatch_type: Optional[str] = "default", - export_filename: Optional[str] = "wallet_export.json", -): +async def main(args): """Run the main function.""" logging.basicConfig(level=logging.WARN) - parsed = urlparse(uri) + parsed = urlparse(args.uri) # Connection setup if parsed.scheme == "sqlite": - conn = SqliteConnection(uri) + conn = SqliteConnection(args.uri) elif parsed.scheme == "postgres": - conn = PgConnection(uri) + conn = PgConnection(args.uri) else: raise ValueError("Unexpected DB URI scheme") # Strategy setup - if strategy == "export": + if args.strategy == "export": + print(args) await conn.connect() method = Exporter( conn=conn, - wallet_name=wallet_name, - wallet_key=wallet_key, - wallet_key_derivation_method=wallet_key_derivation_method, - export_filename=export_filename, + wallet_name=args.wallet_name, + wallet_key=args.wallet_key, + wallet_key_derivation_method=args.wallet_key_derivation_method, + export_filename=args.export_filename, ) - elif strategy == "mt-convert-to-mw": + elif args.strategy == "mt-convert-to-mw": await conn.connect() method = MultiWalletConverter( conn=conn, - wallet_name=wallet_name, - wallet_key=wallet_key, - wallet_key_derivation_method=wallet_key_derivation_method, - sub_wallet_name=multitenant_sub_wallet_name, + wallet_name=args.wallet_name, + wallet_key=args.wallet_key, + wallet_key_derivation_method=args.wallet_key_derivation_method, + sub_wallet_name=args.multitenant_sub_wallet_name, ) - elif strategy == "tenant-import": - tenant_parsed = urlparse(tenant_uri) + elif args.strategy == "tenant-import": + tenant_parsed = urlparse(args.tenant_uri) if tenant_parsed.scheme == "sqlite": - tenant_conn = SqliteConnection(tenant_uri) + tenant_conn = SqliteConnection(args.tenant_uri) elif tenant_parsed.scheme == "postgres": - tenant_conn = PgConnection(tenant_uri) + tenant_conn = PgConnection(args.tenant_uri) else: raise ValueError("Unexpected tenant DB URI scheme") @@ -215,22 +199,24 @@ async def main( await tenant_conn.connect() method = TenantImporter( admin_conn=conn, - admin_wallet_name=wallet_name, - admin_wallet_key=wallet_key, - admin_wallet_key_derivation_method=wallet_key_derivation_method, - tenant_conn=tenant_conn, - tenant_wallet_name=tenant_wallet_name, - tenant_wallet_key=tenant_wallet_key, - tenant_wallet_type=tenant_wallet_type, - tenant_wallet_key_derivation_method=tenant_wallet_key_derivation_method, - tenant_label=tenant_label, - tenant_image_url=tenant_image_url, - tenant_webhook_urls=tenant_webhook_urls, - tenant_extra_settings=tenant_extra_settings, - tenant_dispatch_type=tenant_dispatch_type, + admin_wallet_name=args.wallet_name, + admin_wallet_key=args.wallet_key, + admin_wallet_key_derivation_method=args.wallet_key_derivation_method, + tenant_import_object=TenantImportObject( + tenant_conn=tenant_conn, + tenant_wallet_name=args.tenant_wallet_name, + tenant_wallet_key=args.tenant_wallet_key, + tenant_wallet_type=args.tenant_wallet_type, + tenant_wallet_key_derivation_method=args.tenant_wallet_key_derivation_method, + tenant_label=args.tenant_label, + tenant_image_url=args.tenant_image_url, + tenant_webhook_urls=args.tenant_webhook_urls, + tenant_extra_settings=args.tenant_extra_settings, + tenant_dispatch_type=args.tenant_dispatch_type, + ), ) else: - raise Exception("Invalid strategy") + raise InvalidArgumentsError("Invalid strategy") await method.run() @@ -238,7 +224,7 @@ async def main( def entrypoint(): """Entrypoint for the CLI.""" args = config() - asyncio.run(main(**vars(args))) + asyncio.run(main(args)) if __name__ == "__main__": diff --git a/askar_tools/db_connection.py b/askar_tools/db_connection.py index 0c33408..87f3ce3 100644 --- a/askar_tools/db_connection.py +++ b/askar_tools/db_connection.py @@ -31,5 +31,5 @@ async def create_database(self, admin_wallet_name, sub_wallet_name): """Create a database.""" @abstractmethod - async def remove_wallet(self, admin_wallet_name, sub_wallet_name): - """Remove the wallet.""" + async def remove_database(self, admin_wallet_name, sub_wallet_name): + """Remove the database.""" diff --git a/askar_tools/error.py b/askar_tools/error.py index 4cc43de..fb112fb 100644 --- a/askar_tools/error.py +++ b/askar_tools/error.py @@ -8,3 +8,12 @@ def __init__(self, message): """Initialize the ConversionError object.""" self.message = message print(message) + + +class InvalidArgumentsError(Exception): + """Invalid arguments error.""" + + def __init__(self, message): + """Initialize the InvalidArgumentsError object.""" + self.message = message + print(message) diff --git a/askar_tools/exporter.py b/askar_tools/exporter.py index d64e44a..b5b5969 100644 --- a/askar_tools/exporter.py +++ b/askar_tools/exporter.py @@ -64,7 +64,7 @@ async def export(self): store = await Store.open( self.conn.uri, pass_key=self.wallet_key, - key_method=KEY_METHODS[self.wallet_key_derivation_method], + key_method=KEY_METHODS.get(self.wallet_key_derivation_method), ) tables["items"] = await self._get_decoded_items_and_tags(store) diff --git a/askar_tools/multi_wallet_converter.py b/askar_tools/multi_wallet_converter.py index 942ee6c..0f30d8e 100644 --- a/askar_tools/multi_wallet_converter.py +++ b/askar_tools/multi_wallet_converter.py @@ -133,7 +133,7 @@ async def convert_single_wallet_to_multi_wallet(self): {wallet_record["settings"]["wallet.name"]}. The sub wallet {self.sub_wallet_name} will not be deleted. Try running again.""" ) - await self.conn.remove_wallet( + await self.conn.remove_database( self.admin_wallet_name, wallet_record["settings"]["wallet.name"] ) success = False @@ -141,7 +141,7 @@ async def convert_single_wallet_to_multi_wallet(self): if success: print(f"Deleting sub wallet {self.sub_wallet_name}...") await sub_wallet_store.close() - await self.conn.remove_wallet(self.admin_wallet_name, self.sub_wallet_name) + await self.conn.remove_database(self.admin_wallet_name, self.sub_wallet_name) await admin_store.close() await self.conn.close() diff --git a/askar_tools/pg_connection.py b/askar_tools/pg_connection.py index cc2a164..ee0eb0f 100644 --- a/askar_tools/pg_connection.py +++ b/askar_tools/pg_connection.py @@ -90,11 +90,11 @@ async def create_database(self, admin_wallet_name, sub_wallet_name): """Create an postgres database.""" await self._conn.execute( f""" - CREATE DATABASE {sub_wallet_name}; + CREATE DATABASE "{sub_wallet_name}"; """ ) - async def remove_wallet(self, admin_wallet_name, sub_wallet_name): + async def remove_database(self, admin_wallet_name, sub_wallet_name): """Remove the postgres wallet.""" # Kill any connections to the database await self._conn.execute( @@ -105,6 +105,6 @@ async def remove_wallet(self, admin_wallet_name, sub_wallet_name): # Drop the database await self._conn.execute( f""" - DROP DATABASE {sub_wallet_name}; + DROP DATABASE "{sub_wallet_name}"; """ ) diff --git a/askar_tools/sqlite_connection.py b/askar_tools/sqlite_connection.py index 2b81c8f..17c9736 100644 --- a/askar_tools/sqlite_connection.py +++ b/askar_tools/sqlite_connection.py @@ -1,6 +1,7 @@ import os import shutil import sqlite3 +from typing import Optional from urllib.parse import urlparse import aiosqlite @@ -82,13 +83,20 @@ async def create_database(self, admin_wallet_name, sub_wallet_name): if conn: conn.close() - async def remove_wallet(self, admin_wallet_name, sub_wallet_name): + async def remove_database( + self, + admin_wallet_name: Optional[str] = None, + sub_wallet_name="multitenant_subwallet", + ): """Remove the sqlite wallet.""" - directory = ( - urlparse(self.uri) - .path.replace("/sqlite.db", "") - .replace(admin_wallet_name, sub_wallet_name) - ) + if admin_wallet_name is not None: + directory = ( + urlparse(self.uri) + .path.replace("/sqlite.db", "") + .replace(admin_wallet_name, sub_wallet_name) + ) + else: + directory = urlparse(self.uri).path.replace("/sqlite.db", "") try: shutil.rmtree(directory) print(f"Successfully deleted {directory}") diff --git a/askar_tools/tenant_importer.py b/askar_tools/tenant_importer.py index 584d923..aa219af 100644 --- a/askar_tools/tenant_importer.py +++ b/askar_tools/tenant_importer.py @@ -10,14 +10,11 @@ from .sqlite_connection import SqliteConnection -class TenantImporter: - """The Tenant Importer class.""" +class TenantImportObject: + """The Tenant Import Object class.""" def __init__( self, - admin_conn: SqliteConnection | PgConnection, - admin_wallet_name: str, - admin_wallet_key: str, tenant_conn: SqliteConnection | PgConnection, tenant_wallet_name: str, tenant_wallet_key: str, @@ -27,8 +24,30 @@ def __init__( tenant_webhook_urls: list = None, tenant_extra_settings: dict = None, tenant_dispatch_type: str = "default", - admin_wallet_key_derivation_method: str = "ARGON2I_MOD", tenant_wallet_key_derivation_method: str = "ARGON2I_MOD", + ): + self.tenant_conn = tenant_conn + self.tenant_wallet_name = tenant_wallet_name + self.tenant_wallet_key = tenant_wallet_key + self.tenant_wallet_type = tenant_wallet_type + self.tenant_label = tenant_label + self.tenant_image_url = tenant_image_url + self.tenant_webhook_urls = tenant_webhook_urls + self.tenant_extra_settings = tenant_extra_settings + self.tenant_dispatch_type = tenant_dispatch_type + self.tenant_wallet_key_derivation_method = tenant_wallet_key_derivation_method + + +class TenantImporter: + """The Tenant Importer class.""" + + def __init__( + self, + admin_conn: SqliteConnection | PgConnection, + admin_wallet_name: str, + admin_wallet_key: str, + admin_wallet_key_derivation_method: str, + tenant_import_object: TenantImportObject, ): """Initialize the Tenant Importer object. @@ -36,74 +55,63 @@ def __init__( admin_conn: The admin connection object. admin_wallet_name: The name of the admin wallet. admin_wallet_key: The key for the admin wallet. - tenant_conn: The tenant connection object. - tenant_wallet_name: The name of the tenant wallet. - tenant_wallet_key: The key for the tenant wallet. - tenant_wallet_type: The type of the tenant wallet. - tenant_label: The label for the tenant wallet. - tenant_image_url: The image URL for the tenant wallet. - tenant_webhook_urls: The webhook URLs for the tenant wallet. - tenant_extra_settings: Extra settings for the tenant wallet. - tenant_dispatch_type: The dispatch type for the tenant wallet. - admin_wallet_key_derivation_method: The key derivation method for the admin - wallet. - tenant_wallet_key_derivation_method: The key derivation method for the tenant - wallet. + admin_wallet_key_derivation_method: The key derivation method for the + admin wallet. + tenant_import_object: The tenant import object. """ self.admin_conn = admin_conn self.admin_wallet_name = admin_wallet_name self.admin_wallet_key = admin_wallet_key - self.tenant_conn = tenant_conn - self.tenant_wallet_name = tenant_wallet_name - self.tenant_wallet_key = tenant_wallet_key - self.tenant_wallet_type = tenant_wallet_type - self.tenant_label = tenant_label - self.tenant_image_url = tenant_image_url - self.tenant_webhook_urls = tenant_webhook_urls - self.tenant_extra_settings = tenant_extra_settings - self.tenant_dispatch_type = tenant_dispatch_type self.admin_wallet_key_derivation_method = admin_wallet_key_derivation_method - self.tenant_wallet_key_derivation_method = tenant_wallet_key_derivation_method + self.tenant_import_obj = tenant_import_object async def _create_tenant(self, wallet_id: str, admin_txn, current_time: str): # Create wallet record in admin wallet value_json = { - "wallet_name": self.tenant_wallet_name, + "wallet_name": self.tenant_import_obj.tenant_wallet_name, "created_at": current_time, "updated_at": current_time, "settings": { - "wallet.type": self.tenant_wallet_type, - "wallet.name": self.tenant_wallet_name, - "wallet.key": self.tenant_wallet_key, + "wallet.type": self.tenant_import_obj.tenant_wallet_type, + "wallet.name": self.tenant_import_obj.tenant_wallet_name, + "wallet.key": self.tenant_import_obj.tenant_wallet_key, "wallet.id": wallet_id, - "wallet.key_derivation_method": KEY_METHODS[ - self.tenant_wallet_key_derivation_method - ], - "wallet.dispatch_type": self.tenant_dispatch_type, }, "key_management_mode": "managed", "jwt_iat": current_time, } - if self.tenant_label: - value_json["settings"]["default_label"] = self.tenant_label + if self.tenant_import_obj.tenant_dispatch_type: + value_json["settings"]["wallet.dispatch_type"] = ( + self.tenant_import_obj.tenant_dispatch_type + ) + + if self.tenant_import_obj.tenant_wallet_key_derivation_method: + value_json["settings"]["wallet.key_derivation_method"] = KEY_METHODS[ + self.tenant_import_obj.tenant_wallet_key_derivation_method + ] + + if self.tenant_import_obj.tenant_label: + value_json["settings"]["default_label"] = self.tenant_import_obj.tenant_label - if self.tenant_image_url: - value_json["settings"]["image_url"] = self.tenant_image_url + if self.tenant_import_obj.tenant_image_url: + value_json["settings"]["image_url"] = self.tenant_import_obj.tenant_image_url - if self.tenant_extra_settings: - value_json["settings"].update(self.tenant_extra_settings) + if self.tenant_import_obj.tenant_extra_settings: + value_json["settings"].update(self.tenant_import_obj.tenant_extra_settings) - if self.tenant_webhook_urls: - value_json["settings"]["wallet.webhook_urls"] = self.tenant_webhook_urls + if self.tenant_import_obj.tenant_webhook_urls: + value_json["settings"]["wallet.webhook_urls"] = ( + self.tenant_import_obj.tenant_webhook_urls + ) await admin_txn.insert( category="wallet_record", name=wallet_id, value_json=value_json, tags={ - "wallet_name": self.tenant_wallet_name, + "wallet_name": self.tenant_import_obj.tenant_wallet_name, }, ) @@ -177,48 +185,63 @@ async def import_tenant(self): print("Importing tenant wallet into admin wallet") # Make wallet/db in admin location for tenant - await self.admin_conn.create_database( - admin_wallet_name=self.admin_wallet_name, - sub_wallet_name=self.tenant_wallet_name, - ) - # Copy the tenant wallet to the admin wallet location - tenant_wallet = await Store.open( - uri=self.tenant_conn.uri, - pass_key=self.tenant_wallet_key, - key_method=KEY_METHODS[self.tenant_wallet_key_derivation_method], - ) - await tenant_wallet.copy_to( - target_uri=self.admin_conn.uri.replace( - self.admin_wallet_name, self.tenant_wallet_name - ), - pass_key=self.tenant_wallet_key, - key_method=KEY_METHODS[self.tenant_wallet_key_derivation_method], - ) + success = True + try: + await self.admin_conn.create_database( + admin_wallet_name=self.admin_wallet_name, + sub_wallet_name=self.tenant_import_obj.tenant_wallet_name, + ) + # Copy the tenant wallet to the admin wallet location + tenant_wallet = await Store.open( + uri=self.tenant_import_obj.tenant_conn.uri, + pass_key=self.tenant_import_obj.tenant_wallet_key, + key_method=KEY_METHODS.get( + self.tenant_import_obj.tenant_wallet_key_derivation_method + ), + ) + await tenant_wallet.copy_to( + target_uri=self.admin_conn.uri.replace( + self.admin_wallet_name, self.tenant_import_obj.tenant_wallet_name + ), + pass_key=self.tenant_import_obj.tenant_wallet_key, + key_method=KEY_METHODS.get( + self.tenant_import_obj.tenant_wallet_key_derivation_method + ), + ) - # Import the tenant wallet into the admin wallet - admin_store = await Store.open( - uri=self.admin_conn.uri, - pass_key=self.admin_wallet_key, - key_method=KEY_METHODS[self.admin_wallet_key_derivation_method], - ) - async with admin_store.transaction() as admin_txn: - wallet_id = str(uuid.uuid4()) - current_time = time.time() - await self._create_tenant( - wallet_id=wallet_id, - admin_txn=admin_txn, - current_time=current_time, + # Import the tenant wallet into the admin wallet + admin_store = await Store.open( + uri=self.admin_conn.uri, + pass_key=self.admin_wallet_key, + key_method=KEY_METHODS.get(self.admin_wallet_key_derivation_method), ) - await self._create_forward_routes( - tenant_wallet=tenant_wallet, - admin_txn=admin_txn, - wallet_id=wallet_id, - current_time=current_time, + async with admin_store.transaction() as admin_txn: + wallet_id = str(uuid.uuid4()) + current_time = time.time() + await self._create_tenant( + wallet_id=wallet_id, + admin_txn=admin_txn, + current_time=str(current_time), + ) + await self._create_forward_routes( + tenant_wallet=tenant_wallet, + admin_txn=admin_txn, + wallet_id=wallet_id, + current_time=str(current_time), + ) + await admin_txn.commit() + except Exception as e: + success = False + print(f"Error importing tenant wallet: {e}") + await self.admin_conn.remove_database( + self.admin_wallet_name, self.tenant_import_obj.tenant_wallet_name ) - await admin_txn.commit() + if success: + await tenant_wallet.close() + print("Tenant wallet imported successfully") + await self.tenant_import_obj.tenant_conn.close() await self.admin_conn.close() - await self.tenant_conn.close() async def run(self): """Run the importer.""" diff --git a/askar_tools/tests/e2e/test_export.py b/askar_tools/tests/e2e/test_export.py index 4258647..f6e57aa 100644 --- a/askar_tools/tests/e2e/test_export.py +++ b/askar_tools/tests/e2e/test_export.py @@ -1,4 +1,5 @@ import os +from argparse import Namespace import pytest from acapy_controller import Controller @@ -36,21 +37,31 @@ async def test_export_pg(self, containers: Containers): await test_cases.pre(alice, bob) # Action - await main( - strategy="export", - uri="postgres://postgres:mysecretpassword@localhost:5432/alice", - wallet_name="alice", - wallet_key="3cAZj1hPvUhKeBkzCKPTHhTxRRmYv5abDbjmaYwtk6Nf", - wallet_key_derivation_method="RAW", - export_filename="wallet_export_alice.json", + namespace = Namespace() + namespace.__dict__.update( + { + "strategy": "export", + "uri": "postgres://postgres:mysecretpassword@localhost:5432/alice", + "wallet_name": "alice", + "wallet_key": "3cAZj1hPvUhKeBkzCKPTHhTxRRmYv5abDbjmaYwtk6Nf", + "wallet_key_derivation_method": "RAW", + "export_filename": "wallet_export_alice.json", + } ) - await main( - strategy="export", - uri="postgres://postgres:mysecretpassword@localhost:5432/bob", - wallet_name="bob", - wallet_key="insecure", - export_filename="wallet_export_bob.json", + await main(namespace) + + namespace = Namespace() + namespace.__dict__.update( + { + "strategy": "export", + "uri": "postgres://postgres:mysecretpassword@localhost:5432/bob", + "wallet_name": "bob", + "wallet_key": "insecure", + "wallet_key_derivation_method": "ARGON2I_MOD", + "export_filename": "wallet_export_bob.json", + } ) + await main(namespace) found_alice_export_file = False found_bob_export_file = False @@ -106,23 +117,34 @@ async def test_export_sqlite(self, containers: Containers, tmp_path_factory): containers.fix_permissions(alice_volume_path) containers.fix_permissions(bob_volume_path) - # Action - await main( - strategy="export", - uri=f"sqlite://{alice_volume_path}/sqlite.db", - wallet_name="alice", - wallet_key="3cAZj1hPvUhKeBkzCKPTHhTxRRmYv5abDbjmaYwtk6Nf", - wallet_key_derivation_method="RAW", - export_filename="wallet_export_alice.json", + namespace = Namespace() + namespace.__dict__.update( + { + "strategy": "export", + "uri": f"sqlite://{alice_volume_path}/sqlite.db", + "wallet_name": "alice", + "wallet_key": "3cAZj1hPvUhKeBkzCKPTHhTxRRmYv5abDbjmaYwtk6Nf", + "wallet_key_derivation_method": "RAW", + "export_filename": "wallet_export_alice.json", + } ) - await main( - strategy="export", - uri=f"sqlite://{bob_volume_path}/sqlite.db", - wallet_name="bob", - wallet_key="insecure", - export_filename="wallet_export_alice.json", + # Action + await main(namespace) + + namespace = Namespace() + namespace.__dict__.update( + { + "strategy": "export", + "uri": f"sqlite://{bob_volume_path}/sqlite.db", + "wallet_name": "bob", + "wallet_key": "insecure", + "wallet_key_derivation_method": "ARGON2I_MOD", + "export_filename": "wallet_export_bob.json", + } ) + await main(namespace) + found_alice_export_file = False found_bob_export_file = False for root, dirs, files in os.walk("../"): diff --git a/askar_tools/tests/e2e/test_mt_convert_to_mw.py b/askar_tools/tests/e2e/test_mt_convert_to_mw.py index 8d36ea3..24ea476 100644 --- a/askar_tools/tests/e2e/test_mt_convert_to_mw.py +++ b/askar_tools/tests/e2e/test_mt_convert_to_mw.py @@ -1,3 +1,5 @@ +from argparse import Namespace + import pytest from acapy_controller import Controller from acapy_controller.models import CreateWalletResponse @@ -68,12 +70,18 @@ async def test_conversion_pg(self, containers: Containers): containers.stop(admin_container) # Action the conversion - await main( - strategy="mt-convert-to-mw", - uri="postgres://postgres:mysecretpassword@localhost:5432/admin", - wallet_name="admin", - wallet_key="insecure", + namespace = Namespace() + namespace.__dict__.update( + { + "strategy": "mt-convert-to-mw", + "uri": "postgres://postgres:mysecretpassword@localhost:5432/admin", + "wallet_key_derivation_method": "ARGON2I_MOD", + "wallet_name": "admin", + "wallet_key": "insecure", + "multitenant_sub_wallet_name": "multitenant_sub_wallet", + } ) + await main(namespace) # Start a new admin container that expects multiple wallet for each sub wallet admin_container = containers.acapy_postgres( @@ -169,9 +177,15 @@ async def test_conversion_sqlite(self, containers: Containers, tmp_path_factory) containers.fix_permissions(sub_wallet_volume_path) # Action the conversion - await main( - strategy="mt-convert-to-mw", - uri=f"sqlite://{admin_volume_path}/sqlite.db", - wallet_name="admin", - wallet_key="insecure", + namespace = Namespace() + namespace.__dict__.update( + { + "strategy": "mt-convert-to-mw", + "uri": f"sqlite://{admin_volume_path}/sqlite.db", + "wallet_key_derivation_method": "ARGON2I_MOD", + "wallet_name": "admin", + "wallet_key": "insecure", + "multitenant_sub_wallet_name": "multitenant_sub_wallet", + } ) + await main(namespace) diff --git a/askar_tools/tests/e2e/test_tenant_import.py b/askar_tools/tests/e2e/test_tenant_import.py index 3f338e3..779e828 100644 --- a/askar_tools/tests/e2e/test_tenant_import.py +++ b/askar_tools/tests/e2e/test_tenant_import.py @@ -1,3 +1,5 @@ +from argparse import Namespace + import pytest from acapy_controller import Controller from acapy_controller.models import CreateWalletResponse @@ -65,21 +67,27 @@ async def test_tenant_import_pg(self, containers: Containers): await test_cases.pre(alice, tenant) # Action the import - await main( - strategy="tenant-import", - uri="postgres://postgres:mysecretpassword@localhost:5432/admin", - wallet_name="admin", - wallet_key="insecure", - tenant_uri="postgres://postgres:mysecretpassword@localhost:5433/tenant", - tenant_wallet_name="tenant", - tenant_wallet_key="3cAZj1hPvUhKeBkzCKPTHhTxRRmYv5abDbjmaYwtk6Nf", - tenant_label="Tenant", - tenant_image_url="https://example.com/image.png", - tenant_extra_settings={"extra": "settings"}, - tenant_webhook_urls=["http://example.com/webhook"], - tenant_dispatch_type="default", - tenant_wallet_key_derivation_method="RAW", + namespace = Namespace() + namespace.__dict__.update( + { + "strategy": "tenant-import", + "uri": "postgres://postgres:mysecretpassword@localhost:5432/admin", + "wallet_name": "admin", + "wallet_key": "insecure", + "wallet_key_derivation_method": "ARGON2I_MOD", + "tenant_uri": "postgres://postgres:mysecretpassword@localhost:5433/tenant", + "tenant_wallet_name": "tenant", + "tenant_wallet_key": "3cAZj1hPvUhKeBkzCKPTHhTxRRmYv5abDbjmaYwtk6Nf", + "tenant_wallet_type": "askar", + "tenant_label": "Tenant", + "tenant_image_url": "https://example.com/image.png", + "tenant_extra_settings": {"extra": "settings"}, + "tenant_webhook_urls": ["http://example.com/webhook"], + "tenant_dispatch_type": "default", + "tenant_wallet_key_derivation_method": "RAW", + } ) + await main(namespace) async with Controller("http://localhost:3001") as admin: # Get the tenant wallet id and token