diff options
author | Florian Dold <florian@dold.me> | 2023-10-06 02:11:55 +0200 |
---|---|---|
committer | Florian Dold <florian@dold.me> | 2023-10-06 02:11:55 +0200 |
commit | a2e6825908e6fb0271bbc58d849fd6480d013316 (patch) | |
tree | b4e54c1e4fa3500c1dc144f7676e5470d8f03e6b | |
parent | 80a518748cc74cabe52d96b59022ab5792aa815a (diff) | |
download | libeufin-a2e6825908e6fb0271bbc58d849fd6480d013316.tar.gz libeufin-a2e6825908e6fb0271bbc58d849fd6480d013316.tar.bz2 libeufin-a2e6825908e6fb0271bbc58d849fd6480d013316.zip |
cleanup
-rw-r--r-- | build.gradle | 35 | ||||
-rwxr-xr-x | cli/bin/libeufin-cli | 2004 | ||||
-rwxr-xr-x | cli/tests/add-incoming-client.sh | 7 | ||||
-rwxr-xr-x | cli/tests/circuit_test.sh | 118 | ||||
-rwxr-xr-x | cli/tests/circuit_test_email_tan.sh | 83 | ||||
-rwxr-xr-x | cli/tests/circuit_test_file_tan.sh | 126 | ||||
-rwxr-xr-x | cli/tests/debit_test.sh | 77 | ||||
-rwxr-xr-x | cli/tests/launch_services_with_ebics.sh | 106 | ||||
-rwxr-xr-x | cli/tests/launch_services_with_xlibeufinbank.sh | 118 | ||||
l--------- | cli/tests/libeufin-cli | 1 | ||||
-rwxr-xr-x | cli/tests/registration_test.sh | 43 | ||||
-rwxr-xr-x | cli/tests/twg-history-loop.sh | 21 | ||||
-rwxr-xr-x | cli/tests/wire-transfer.sh | 14 | ||||
-rw-r--r-- | cli/tests/wirewatch.conf | 11 |
14 files changed, 0 insertions, 2764 deletions
diff --git a/build.gradle b/build.gradle index c248edf6..5d5873d7 100644 --- a/build.gradle +++ b/build.gradle @@ -48,41 +48,6 @@ task libeufinVersion { } } -task replaceVersionCli(type: Copy) { - from file("cli/bin/libeufin-cli") - into file("${project.buildDir}/generated/python") - filter(ReplaceTokens, tokens: [version: getRootProject().version]) -} - classes { dependsOn versionFile - dependsOn replaceVersionCli -} - -task execArch(type: Zip) { - dependsOn versionFile - dependsOn replaceVersionCli - // evaluationDependsOn("nexus") - evaluationDependsOn("bank") - def topDir = "${getRootProject().name}-${getRootProject().version}" - archiveFileName = "${topDir}.zip" - subprojects.each { - if (it.name == "nexus" || it.name == "bank") { - Task t = it.tasks.getByName("installShadowDist") - dependsOn(t) // invokes the task 't' - } - } - //from("nexus/build/install/nexus-shadow") { - // include("**/libeufin-nexus") - // include("**/*.jar") - //} - from("bank/build/install/bank-shadow") { - include("**/libeufin-bank") - include("**/*.jar") - } - from("${project.buildDir}/generated/python") { - include("libeufin-cli") - rename { "bin/libeufin-cli" } - } - into(topDir) } diff --git a/cli/bin/libeufin-cli b/cli/bin/libeufin-cli deleted file mode 100755 index 9a7471ab..00000000 --- a/cli/bin/libeufin-cli +++ /dev/null @@ -1,2004 +0,0 @@ -#!/usr/bin/env python3 - -import os -import sys -import click -import json -import hashlib -import errno -from datetime import datetime -import requests - -# FIXME: always use qualified name -from requests import post, get, auth, delete, patch -from urllib.parse import urljoin -from getpass import getpass - -# Prepares the 'auth' option to pass to requests. -def maybe_auth(sandbox_ctx): - if (sandbox_ctx.credentials_found): - return dict( - auth=auth.HTTPBasicAuth( - sandbox_ctx.username, - sandbox_ctx.password - ) - ) - return dict() - - -# Gets the account name to use in a request. It gives -# precedence to the account name passed along the CLI options, -# and falls back to the account name found in the environment. -# It returns None if no account was found, or that was 'admin'. -# Admin is excluded because it isn't modeled like ordinary -# customers and would therefore very likely hit != 2xx response -# statuses. -def get_account_name(accountNameCli, usernameEnv): - maybeUsername = accountNameCli - if not maybeUsername: - maybeUsername = usernameEnv - if not maybeUsername: - print("No username was found", file=sys.stderr) - return None - if maybeUsername == "admin": - print("admin username not suitable", file=sys.stderr) - return None - return maybeUsername - -# Exit the program according to the HTTP status code that -# was received. -def check_response_status(resp, expected_status_code=200): - if resp.status_code != expected_status_code: - print("Unexpected response status: {}".format(resp.status_code), file=sys.stderr) - print("Response: {}".format(resp.text), file=sys.stderr) - sys.exit(1) - -# Prints the response body. -def tell_user(resp): - print(resp.content.decode("utf-8")) - -# Normalize the two components to "x/" and "y" and pass them -# to urljoin(). This avoids drop-policies from plain urljoin(). -def urljoin_nodrop(a, b): - a = a + "/" # urljoin will drop extra trailing slashes. - b = "/".join([x for x in b.split("/") if x != ""]) # remove leading slashes. - return urljoin(a, b) - -# FIXME: deprecate this in favor of NexusContext -def fetch_env(): - if "--help" in sys.argv: - return [] - try: - nexus_base_url = os.environ["LIBEUFIN_NEXUS_URL"] - nexus_username = os.environ["LIBEUFIN_NEXUS_USERNAME"] - nexus_password = os.environ["LIBEUFIN_NEXUS_PASSWORD"] - except KeyError: - print( - "Please ensure that LIBEUFIN_NEXUS_URL," - " LIBEUFIN_NEXUS_USERNAME, LIBEUFIN_NEXUS_PASSWORD exist" - " in the environment" - ) - sys.exit(1) - return nexus_base_url, nexus_username, nexus_password - - -# FIXME: deprecate this in favor of NexusContext -class NexusAccess: - def __init__(self, nexus_base_url=None, username=None, password=None): - self.nexus_base_url = nexus_base_url - self.username = username - self.password = password - - -@click.group(help="General utility to invoke HTTP REST services offered by Nexus.") -@click.version_option(version="0.0.1-dev.1") -def cli(): - pass - - -@cli.group() -@click.pass_context -def facades(ctx): - ctx.obj = NexusAccess(*fetch_env()) - - -@cli.group() -@click.pass_context -def connections(ctx): - ctx.obj = NexusAccess(*fetch_env()) - - -@cli.group() -@click.pass_context -def users(ctx): - ctx.obj = NexusContext() - - -@cli.group() -@click.pass_context -def permissions(ctx): - ctx.obj = NexusContext() - -@users.command("self", help="Show information about authenticated user.") -@click.pass_obj -def users_self(obj): - url = urljoin_nodrop(obj.nexus_base_url, f"/user") - try: - resp = get(url, auth=auth.HTTPBasicAuth(obj.nexus_username, obj.nexus_password)) - except Exception as e: - print(e) - print("Could not reach nexus at " + url) - exit(1) - - check_response_status(resp) - tell_user(resp) - -@users.command("list", help="List users") -@click.pass_obj -def list_users(obj): - url = urljoin_nodrop(obj.nexus_base_url, f"/users") - try: - resp = get(url, auth=auth.HTTPBasicAuth(obj.nexus_username, obj.nexus_password)) - except Exception as e: - print(e) - print("Could not reach nexus at " + url) - exit(1) - - check_response_status(resp) - tell_user(resp) - - -@users.command(help="Change user's password (as superuser)") -@click.argument("username") -@click.option( - "--new-password", - help="New password", - prompt=True, - hide_input=True, - confirmation_prompt=True, -) -@click.pass_obj -def change_password(obj, username, new_password): - url = urljoin_nodrop(obj.nexus_base_url, f"/users/{username}/password") - try: - body = dict(newPassword=new_password) - resp = post( - url, - json=body, - auth=auth.HTTPBasicAuth(obj.nexus_username, obj.nexus_password), - ) - except Exception as e: - print(e) - print("Could not reach nexus at " + url) - exit(1) - - check_response_status(resp) - tell_user(resp) - - -@users.command("create", help="Create a new user without superuser privileges") -@click.argument("username") -@click.option( - "--password", - help="Provide password instead of prompting interactively.", - prompt=True, - hide_input=True, - confirmation_prompt=True, -) -@click.pass_obj -def create_user(obj, username, password): - url = urljoin_nodrop(obj.nexus_base_url, f"/users") - try: - body = dict( - username=username, - password=password, - ) - resp = post( - url, - json=body, - auth=auth.HTTPBasicAuth(obj.nexus_username, obj.nexus_password), - ) - except Exception as e: - print(e) - print("Could not reach nexus at " + url) - exit(1) - - print(resp.content.decode("utf-8")) - check_response_status(resp) - - -@permissions.command("list", help="Show permissions") -@click.pass_obj -def list_permission(obj): - url = urljoin_nodrop(obj.nexus_base_url, f"/permissions") - try: - resp = get(url, auth=auth.HTTPBasicAuth(obj.nexus_username, obj.nexus_password)) - except Exception as e: - print(e) - print("Could not reach nexus at " + url) - exit(1) - - print(resp.content.decode("utf-8")) - check_response_status(resp) - - -@permissions.command("grant", help="Grant permission to a subject") -@click.pass_obj -@click.argument("subject-type") -@click.argument("subject-id") -@click.argument("resource-type") -@click.argument("resource-id") -@click.argument("permission-name") -def grant_permission( - obj, subject_type, subject_id, resource_type, resource_id, permission_name -): - url = urljoin_nodrop(obj.nexus_base_url, f"/permissions") - try: - permission = dict( - subjectType=subject_type, - subjectId=subject_id, - resourceType=resource_type, - resourceId=resource_id, - permissionName=permission_name, - ) - body = dict( - permission=permission, - action="grant", - ) - resp = post( - url, - json=body, - auth=auth.HTTPBasicAuth(obj.nexus_username, obj.nexus_password), - ) - except Exception as e: - print(e) - print("Could not reach nexus at " + url) - exit(1) - - print(resp.content.decode("utf-8")) - check_response_status(resp) - - -@permissions.command("revoke", help="Revoke permission from a subject") -@click.pass_obj -@click.argument("subject-type") -@click.argument("subject-id") -@click.argument("resource-type") -@click.argument("resource-id") -@click.argument("permission-name") -def revoke_permission( - obj, subject_type, subject_id, resource_type, resource_id, permission_name -): - url = urljoin_nodrop(obj.nexus_base_url, f"/permissions") - try: - permission = dict( - subjectType=subject_type, - subjectId=subject_id, - resourceType=resource_type, - resourceId=resource_id, - permissionName=permission_name, - ) - body = dict( - permission=permission, - action="revoke", - ) - resp = post( - url, - json=body, - auth=auth.HTTPBasicAuth(obj.nexus_username, obj.nexus_password), - ) - except Exception as e: - print(e) - print("Could not reach nexus at " + url) - exit(1) - - print(resp.content.decode("utf-8")) - check_response_status(resp) - - -@cli.group() -@click.pass_context -def accounts(ctx): - ctx.obj = NexusAccess(*fetch_env()) - - -class SandboxContext: - def __init__(self): - self.sandbox_base_url = None - self.demobank_name = None - self.init_sandbox_credentials() - if not self.credentials_found: - print("""INFO: LIBEUFIN_SANDBOX_USERNAME or LIBEUFIN_SANDBOX_PASSWORD -not found in the environment. Won't authenticate""" - ) - - def init_sandbox_credentials(self): - self.username = os.environ.get("LIBEUFIN_SANDBOX_USERNAME") - self.password = os.environ.get("LIBEUFIN_SANDBOX_PASSWORD") - self.credentials_found = False - if self.username and self.password: - self.credentials_found = True - - def require_sandbox_base_url(self): - if self.sandbox_base_url: - return self.sandbox_base_url - sandbox_base_url = os.environ.get("LIBEUFIN_SANDBOX_URL") - if not sandbox_base_url: - raise click.UsageError( - "sandbox URL must be given as an argument or in LIBEUFIN_SANDBOX_URL" - ) - return sandbox_base_url - - def access_api_url(self, upath): - base = self.require_sandbox_base_url() - # return urljoin_nodrop(demobank_base, "/access-api" + upath) - return urljoin_nodrop(self.demobank_base_url(), "/access-api" + upath) - - # Empty upath gets just the slash-ended circuit API URL initial segment. - def circuit_api_url(self, upath): - circuit_base_url = urljoin_nodrop(self.demobank_base_url(), "/circuit-api") - return urljoin_nodrop(circuit_base_url, upath) - - def demobank_base_url(self): - base = self.require_sandbox_base_url() - return urljoin_nodrop(base, f"demobanks/{self.demobank_name}") - -class NexusContext: - def __init__(self): - self._nexus_base_url = None - self._nexus_password = None - self._nexus_username = None - - @property - def nexus_base_url(self): - if self._nexus_base_url: - return self._nexus_base_url - val = os.environ.get("LIBEUFIN_NEXUS_URL") - if not val: - raise click.UsageError( - "nexus URL not found in LIBEUFIN_NEXUS_URL" - ) - self._nexus_base_url = val - return val - - @property - def nexus_username(self): - if self._nexus_username: - return self._nexus_username - val = os.environ.get("LIBEUFIN_NEXUS_USERNAME") - if not val: - raise click.UsageError( - "Could not find the username in LIBEUFIN_NEXUS_USERNAME" - ) - self._nexus_username = val - return val - - @property - def nexus_password(self): - if self._nexus_password: - return self._nexus_password - val = os.environ.get("LIBEUFIN_NEXUS_PASSWORD") - if not val: - raise click.UsageError( - "Could not find the password in LIBEUFIN_NEXUS_PASSWORD" - ) - self._nexus_password = val - return val - - -@cli.group() -@click.option("--sandbox-url", help="URL for the sandbox", required=False) -@click.pass_context -def sandbox(ctx, sandbox_url): - ctx.obj = SandboxContext() - ctx.obj.sandbox_base_url = sandbox_url - - -@connections.command(help="Get key letter (typically PDF).") -@click.argument("connection-name") -@click.argument("output_file") -@click.pass_obj -def get_key_letter(obj, connection_name, output_file): - url = urljoin_nodrop(obj.nexus_base_url, f"/bank-connections/{connection_name}/keyletter") - try: - resp = get(url, auth=auth.HTTPBasicAuth(obj.username, obj.password)) - except Exception as e: - print(e) - print("Could not reach nexus at " + url) - exit(1) - - check_response_status(resp) - - output = open(output_file, "wb") - output.write(resp.content) - output.close() - -@connections.command(help="export backup") -@click.option("--passphrase", help="Passphrase for locking the backup", required=True) -@click.option("--output-file", help="Where to store the backup", required=True) -@click.argument("connection-name") -@click.pass_obj -def export_backup(obj, connection_name, passphrase, output_file): - url = urljoin_nodrop( - obj.nexus_base_url, "/bank-connections/{}/export-backup".format(connection_name) - ) - try: - resp = post( - url, - json=dict(passphrase=passphrase), - auth=auth.HTTPBasicAuth(obj.username, obj.password), - ) - except Exception as e: - print(e) - print("Could not reach nexus at " + url) - exit(1) - - # Will exit upon errors. - check_response_status(resp) - - output = open(output_file, "w+") - output.write(resp.content.decode("utf-8")) - output.close() - - print("Backup stored in {}".format(output_file)) - - -@connections.command(help="delete bank connection") -@click.argument("connection-name") -@click.pass_obj -def delete_connection(obj, connection_name): - - url = urljoin_nodrop(obj.nexus_base_url, "/bank-connections/delete-connection") - try: - resp = post( - url, - json=dict(bankConnectionId=connection_name), - auth=auth.HTTPBasicAuth(obj.username, obj.password), - ) - except Exception as e: - print(e) - print("Could not reach nexus at " + url) - exit(1) - - check_response_status(resp) - - -@connections.command(help="restore backup") -@click.option("--backup-file", help="Back file", required=True) -@click.option("--passphrase", help="Passphrase for locking the backup", required=True) -@click.argument("connection-name") -@click.pass_obj -def restore_backup(obj, backup_file, passphrase, connection_name): - url = urljoin_nodrop(obj.nexus_base_url, "/bank-connections") - try: - backup = open(backup_file, "r") - except Exception as e: - print(e) - print("Could not open the backup at {}".format(backup_file)) - exit(1) - backup_json = json.loads(backup.read()) - backup.close() - - try: - resp = post( - url, - json=dict( - name=connection_name, - data=backup_json, - passphrase=passphrase, - source="backup", - ), - auth=auth.HTTPBasicAuth(obj.username, obj.password), - ) - except Exception as e: - print(e) - print("Could not reach nexus at " + url) - exit(1) - - check_response_status(resp) - - -@connections.command(help="make a new x-libeufin-bank connection") -@click.option( - "--bank-url", - help="Bank base URL, typically ending with '../demobanks/default/access-api'", - required=True -) -@click.option( - "--username", - help="Username at the bank, that this connection impersonates.", - required=True -) -@click.password_option() -@click.argument("connection-name") -@click.pass_obj -def new_xlibeufinbank_connection(obj, bank_url, username, password, connection_name): - url = urljoin_nodrop(obj.nexus_base_url, "/bank-connections") - body = dict( - name=connection_name, - source="new", - type="x-libeufin-bank", - data=dict( - baseUrl=bank_url, - username=username, - password=password - ), - ) - try: - resp = post( - url, - json=body, - auth=auth.HTTPBasicAuth(obj.username, obj.password) - ) - except Exception as e: - print(e) - print(f"Could not reach nexus at {url}") - exit(1) - - check_response_status(resp) - -@connections.command(help="make new EBICS bank connection") -@click.option("--ebics-url", help="EBICS URL", required=True) -@click.option("--host-id", help="Host ID", required=True) -@click.option("--partner-id", help="Partner ID", required=True) -@click.option("--ebics-user-id", help="Ebics user ID", required=True) -@click.option( - "--dialect", - help="EBICS dialect of this connection", - required=False -) -@click.argument("connection-name") -@click.pass_obj -def new_ebics_connection( - obj, connection_name, ebics_url, host_id, partner_id, ebics_user_id, dialect -): - url = urljoin_nodrop(obj.nexus_base_url, "/bank-connections") - body = dict( - name=connection_name, - source="new", - type="ebics", - data=dict( - ebicsURL=ebics_url, - hostID=host_id, - partnerID=partner_id, - userID=ebics_user_id, - dialect=dialect - ), - ) - try: - resp = post(url, json=body, auth=auth.HTTPBasicAuth(obj.username, obj.password)) - except Exception as e: - print(e) - print(f"Could not reach nexus at {url}") - exit(1) - - check_response_status(resp) - -@connections.command(help="Initialize the bank connection.") -@click.argument("connection-name") -@click.pass_obj -def connect(obj, connection_name): - url = urljoin_nodrop(obj.nexus_base_url, f"/bank-connections/{connection_name}/connect") - try: - resp = post( - url, json=dict(), auth=auth.HTTPBasicAuth(obj.username, obj.password) - ) - except Exception as e: - print(e) - print(f"Could not reach nexus at {url}") - exit(1) - - check_response_status(resp) - -@connections.command(help="Import one bank account, chosen from the downloaded ones.") -@click.option( - "--offered-account-id", help="Name of the account to import", required=True -) -@click.option( - "--nexus-bank-account-id", - help="Name to give to the imported account", - required=True, -) -@click.argument("connection-name") -@click.pass_obj -def import_bank_account( - obj, connection_name, offered_account_id, nexus_bank_account_id -): - url = urljoin_nodrop( - obj.nexus_base_url, - "/bank-connections/{}/import-account".format(connection_name), - ) - try: - resp = post( - url, - json=dict( - offeredAccountId=offered_account_id, - nexusBankAccountId=nexus_bank_account_id, - ), - auth=auth.HTTPBasicAuth(obj.username, obj.password), - ) - except Exception as e: - print(f"Could not reach nexus at {url}: {e}") - exit(1) - - check_response_status(resp) - - -@connections.command( - help="Update list of bank accounts available through this connection." -) -@click.argument("connection-name") -@click.pass_obj -def download_bank_accounts(obj, connection_name): - url = urljoin_nodrop( - obj.nexus_base_url, - "/bank-connections/{}/fetch-accounts".format(connection_name), - ) - try: - resp = post( - url, json=dict(), auth=auth.HTTPBasicAuth(obj.username, obj.password) - ) - except Exception as e: - print(e) - print("Could not reach nexus at " + url) - exit(1) - - check_response_status(resp) - - -@connections.command(help="List the connections.") -@click.pass_obj -def list_connections(obj): - url = urljoin_nodrop(obj.nexus_base_url, "/bank-connections") - try: - resp = get( - url, json=dict(), auth=auth.HTTPBasicAuth(obj.username, obj.password) - ) - except Exception as e: - print(e) - print("Could not reach nexus at " + url) - exit(1) - - check_response_status(resp) - tell_user(resp) - - -@connections.command(help="Show the status of a bank connection.") -@click.argument("connection-name") -@click.pass_obj -def show_connection(obj, connection_name): - url = urljoin_nodrop(obj.nexus_base_url, f"/bank-connections/{connection_name}") - try: - resp = get( - url, json=dict(), auth=auth.HTTPBasicAuth(obj.username, obj.password) - ) - except Exception as e: - print(e) - print("Could not reach nexus at " + url) - exit(1) - - check_response_status(resp) - tell_user(resp) - - -@connections.command(help="list bank accounts hosted at one connection") -@click.argument("connection-name") -@click.pass_obj -def list_offered_bank_accounts(obj, connection_name): - url = urljoin_nodrop( - obj.nexus_base_url, "/bank-connections/{}/accounts".format(connection_name) - ) - try: - resp = get( - url, json=dict(), auth=auth.HTTPBasicAuth(obj.username, obj.password) - ) - except Exception as e: - print(e) - print("Could not reach nexus at " + url) - exit(1) - - check_response_status(resp) - tell_user(resp) - - -@accounts.command(help="Schedules a new task") -@click.argument("account-name") -@click.option("--task-name", help="Name of the task", required=True) -@click.option("--task-cronspec", help="Cronspec string", required=True) -@click.option( - "--task-type", - help="'fetch' (downloads transactions histories) or 'submit' (uploads payments instructions)", - required=True, -) -@click.option( - "--task-param-range-type", - help="Only needed for 'fetch'. (FIXME: link to documentation here!)", - required=False, -) -@click.option( - "--task-param-level", - help="Only needed for 'fetch'. (FIXME: link to documentation here!)", - required=False, -) -@click.pass_obj -def task_schedule( - obj, - account_name, - task_name, - task_cronspec, - task_type, - task_param_range_type, - task_param_level, -): - - url = urljoin_nodrop(obj.nexus_base_url, "/bank-accounts/{}/schedule".format(account_name)) - body = dict(name=task_name, cronspec=task_cronspec, type=task_type) - if task_type == "fetch" and not (task_param_range_type or task_param_level): - print("'fetch' type requires --task-param-range-type and --task-param-level") - return - - body.update( - dict(params=dict(rangeType=task_param_range_type, level=task_param_level)) - ) - try: - resp = post(url, json=body, auth=auth.HTTPBasicAuth(obj.username, obj.password)) - except Exception as e: - print(e) - print("Could not reach nexus at " + url) - exit(1) - - check_response_status(resp) - - -@accounts.command(help="Show the status of a task") -@click.argument("account-name") -@click.option("--task-name", help="Name of the task", required=True) -@click.pass_obj -def task_status(obj, account_name, task_name): - url = urljoin_nodrop( - obj.nexus_base_url, - "/bank-accounts/{}/schedule/{}".format(account_name, task_name), - ) - try: - resp = get(url, auth=auth.HTTPBasicAuth(obj.username, obj.password)) - except Exception as e: - print(e) - print("Could not reach nexus " + url) - exit(1) - - check_response_status(resp) - tell_user(resp) - - -@accounts.command(help="Delete a task") -@click.argument("account-name") -@click.option("--task-name", help="Name of the task", required=True) -@click.pass_obj -def task_delete(obj, account_name, task_name): - url = urljoin_nodrop( - obj.nexus_base_url, - "/bank-accounts/{}/schedule/{}".format(account_name, task_name), - ) - try: - resp = delete(url, auth=auth.HTTPBasicAuth(obj.username, obj.password)) - except Exception as e: - print(e) - print("Could not reach nexus " + url) - exit(1) - - check_response_status(resp) - - -@accounts.command("list-tasks", help="List all the configured tasks") -@click.argument("account-name") -@click.pass_obj -def tasks_show(obj, account_name): - url = urljoin_nodrop(obj.nexus_base_url, "/bank-accounts/{}/schedule".format(account_name)) - try: - resp = get(url, auth=auth.HTTPBasicAuth(obj.username, obj.password)) - except Exception as e: - print(e) - print("Could not reach nexus " + url) - exit(1) - - check_response_status(resp) - tell_user(resp) - - -@accounts.command(help="Show accounts belonging to calling user") -@click.pass_obj -def show(obj): - url = urljoin_nodrop(obj.nexus_base_url, "/bank-accounts") - try: - resp = get(url, auth=auth.HTTPBasicAuth(obj.username, obj.password)) - except Exception as e: - print(f"Could not reach nexus at {url}, error: {e}") - exit(1) - - check_response_status(resp) - tell_user(resp) - - -@accounts.command(help="Prepare payment initiation debiting the account.") -@click.option( - "--creditor-iban", help="IBAN that will receive the payment", required=True -) -@click.option( - "--creditor-bic", help="BIC that will receive the payment", required=False -) -@click.option( - "--creditor-name", help="Legal name that will receive the payment", required=True -) -@click.option( - "--payment-amount", help="Amount to be paid (<currency>:X.Y)", required=True -) -@click.option("--payment-subject", help="Subject of this payment", required=True) -@click.argument("account-name") -@click.pass_obj -def prepare_payment( - obj, - account_name, - creditor_iban, - creditor_bic, - creditor_name, - payment_amount, - payment_subject, -): - url = urljoin_nodrop( - obj.nexus_base_url, "/bank-accounts/{}/payment-initiations".format(account_name) - ) - body = dict( - iban=creditor_iban, - bic=creditor_bic, - name=creditor_name, - subject=payment_subject, - amount=payment_amount, - ) - - try: - resp = post(url, json=body, auth=auth.HTTPBasicAuth(obj.username, obj.password)) - except Exception as e: - print(e) - print("Could not reach nexus at " + url) - exit(1) - - check_response_status(resp) - - -@accounts.command(help="Submit a payment initiation. Submit every new payment if invoked without options.") -@click.option("--payment-uuid", help="Payment unique identifier. Submits only this payment.") -@click.argument("account-name") -@click.pass_obj -def submit_payments(obj, account_name, payment_uuid): - if payment_uuid: - url = urljoin_nodrop( - obj.nexus_base_url, - "/bank-accounts/{}/payment-initiations/{}/submit".format( - account_name, payment_uuid - ), - ) - else: - url = urljoin_nodrop( - obj.nexus_base_url, - "/bank-accounts/{}/submit-all-payment-initiations".format( - account_name - ), - ) - try: - resp = post( - url, json=dict(), auth=auth.HTTPBasicAuth(obj.username, obj.password) - ) - except Exception as e: - print(e) - print("Could not reach nexus at" + url) - exit(1) - - check_response_status(resp) - - -@accounts.command(help="Show status of a payment initiation") -@click.option("--payment-uuid", help="payment unique identifier", required=True) -@click.argument("account-name") -@click.pass_obj -def show_payment(obj, account_name, payment_uuid): - url = urljoin_nodrop( - obj.nexus_base_url, - f"/bank-accounts/{account_name}/payment-initiations/{payment_uuid}", - ) - try: - resp = get(url, auth=auth.HTTPBasicAuth(obj.username, obj.password)) - except Exception as e: - print(e) - print("Could not reach nexus at" + url) - exit(1) - - check_response_status(resp) - tell_user(resp) - - -@accounts.command(help="List payment initiations") -@click.argument("account-name") -@click.pass_obj -def list_payments(obj, account_name): - url = urljoin_nodrop( - obj.nexus_base_url, f"/bank-accounts/{account_name}/payment-initiations" - ) - try: - resp = get(url, auth=auth.HTTPBasicAuth(obj.username, obj.password)) - except Exception as e: - print(e) - print("Could not reach nexus at" + url) - exit(1) - - check_response_status(resp) - tell_user(resp) - - -@accounts.command(help="Delete a payment initiation") -@click.argument("account-name") -@click.option("--payment-uuid", help="payment unique identifier", required=True) -@click.pass_obj -def delete_payment(obj, account_name, payment_uuid): - url = urljoin_nodrop( - obj.nexus_base_url, - f"/bank-accounts/{account_name}/payment-initiations/{payment_uuid}", - ) - try: - resp = delete(url, auth=auth.HTTPBasicAuth(obj.username, obj.password)) - except Exception as e: - print(e) - print("Could not reach nexus at" + url) - exit(1) - - check_response_status(resp) - - -@accounts.command(help="Fetch transactions from the bank") -@click.option( - "--range-type", - default="all", - help="Admitted values: all, latest, previous-days, since-last, time-range", -) -@click.option("--level", default="all", help="Admitted values: report, statement, all") -@click.option("--start", help="If --range-type is 'time-range', this option holds the (inclusive) starting date in the format YYYY-MM-DD. If missing, it defaults to 1970-01-01.") -@click.option("--end", help="If --range-type is 'time-range', this option holds the (inclusive) ending date in the format YYYY-MM-DD. If missing, it defaults to the present date.") -@click.argument("account-name") -@click.pass_obj -def fetch_transactions(obj, account_name, range_type, level, start, end): - url = urljoin_nodrop( - obj.nexus_base_url, "/bank-accounts/{}/fetch-transactions".format(account_name) - ) - body = dict(rangeType=range_type, level=level) - if range_type == "time-range": - start_value = start if start else "1970-01-01" - end_value = end if end else datetime.today().strftime("%Y-%m-%d") - body.update(dict(start=start_value, end=end_value)) - try: - resp = requests.post( - url, - json=body, - auth=auth.HTTPBasicAuth(obj.username, obj.password), - ) - except Exception as e: - print(e) - print("Could not reach nexus " + url) - exit(1) - - check_response_status(resp) - tell_user(resp) - -@accounts.command(help="Get transactions from the simplified nexus JSON API") -@click.option( - "--compact/--no-compact", - help="Tells only amount/subject for each payment", - required=False, - default=False, -) -@click.argument("account-name") -@click.pass_obj -def transactions(obj, compact, account_name): - url = urljoin_nodrop( - obj.nexus_base_url, "/bank-accounts/{}/transactions".format(account_name) - ) - try: - resp = get(url, auth=auth.HTTPBasicAuth(obj.username, obj.password)) - except Exception as e: - print(e) - print("Could not reach nexus " + url) - exit(1) - - if compact and resp.status_code == 200: - for payment in resp.json()["transactions"]: - for entry in payment["batches"]: - for expected_singleton in entry["batchTransactions"]: - print( - "{}, {}".format( - expected_singleton["details"][ - "unstructuredRemittanceInformation" - ], - expected_singleton["amount"], - ) - ) - else: - tell_user(resp) - check_response_status(resp) - - -@facades.command("list", help="List active facades in the Nexus") -@click.pass_obj -def list_facades(obj): - url = urljoin_nodrop(obj.nexus_base_url, "/facades") - try: - resp = get(url, auth=auth.HTTPBasicAuth(obj.username, obj.password)) - except Exception as e: - print(f"Could not reach nexus (at {obj.nexus_base_url}): {e}") - exit(1) - - check_response_status(resp) - tell_user(resp) - - -@facades.command( - "new-anastasis-facade", help="create a new Anastasis facade" -) -@click.option("--facade-name", help="Name of the facade", required=True) -@click.option("--currency", help="Facade's currency", required=True) -@click.argument("connection-name") -@click.argument("account-name") -@click.pass_obj -def new_anastasis_facade(obj, facade_name, connection_name, account_name, currency): - url = urljoin_nodrop(obj.nexus_base_url, "/facades") - try: - resp = post( - url, - auth=auth.HTTPBasicAuth(obj.username, obj.password), - json=dict( - name=facade_name, - type="anastasis", - config=dict( - currency=currency, - bankAccount=account_name, - bankConnection=connection_name, - reserveTransferLevel="UNUSED", - intervalIncremental="UNUSED", - ), - ), - ) - except Exception as e: - print(f"Could not reach nexus (at {obj.nexus_base_url}): {e}") - exit(1) - - check_response_status(resp) - - -@facades.command( - "new-taler-wire-gateway-facade", help="create a new Taler Wire Gateway facade" -) -@click.option("--facade-name", help="Name of the facade", required=True) -@click.option("--currency", help="Facade's currency", required=True) -@click.argument("connection-name") -@click.argument("account-name") -@click.pass_obj -def new_twg_facade(obj, facade_name, connection_name, account_name, currency): - url = urljoin_nodrop(obj.nexus_base_url, "/facades") - try: - resp = post( - url, - auth=auth.HTTPBasicAuth(obj.username, obj.password), - json=dict( - name=facade_name, - type="taler-wire-gateway", - config=dict( - currency=currency, - bankAccount=account_name, - bankConnection=connection_name, - reserveTransferLevel="UNUSED", - intervalIncremental="UNUSED", - ), - ), - ) - except Exception as e: - print(f"Could not reach nexus (at {obj.nexus_base_url}): {e}") - exit(1) - - check_response_status(resp) - - -@sandbox.group("ebicshost", help="manage EBICS hosts") -@click.pass_context -def sandbox_ebicshost(ctx): - pass - - -@sandbox.command("check", help="check sandbox status") -@click.pass_obj -def check_sandbox_status(obj): - sandbox_base_url = obj.require_sandbox_base_url() - url = urljoin_nodrop(sandbox_base_url, "/") - try: - resp = get(url) - except Exception as e: - print(e) - print("Could not reach sandbox") - exit(1) - - check_response_status(resp) - tell_user(resp) - - -@sandbox_ebicshost.command("create", help="Create an EBICS host") -@click.option("--host-id", help="EBICS host ID", required=True, prompt=True) -@click.pass_obj -def make_ebics_host(obj, host_id): - sandbox_base_url = obj.require_sandbox_base_url() - url = urljoin_nodrop(sandbox_base_url, "/admin/ebics/hosts") - try: - resp = post( - url, - json=dict(hostID=host_id, ebicsVersion="2.5"), - **maybe_auth(obj) - ) - except Exception as e: - print(e) - print("Could not reach sandbox") - exit(1) - - check_response_status(resp) - - -@sandbox_ebicshost.command("list", help="List EBICS hosts.") -@click.pass_obj -def list_ebics_host(obj): - sandbox_base_url = obj.require_sandbox_base_url() - url = urljoin_nodrop(sandbox_base_url, "/admin/ebics/hosts") - try: - resp = get(url, **maybe_auth(obj)) - except Exception as e: - print(e) - print("Could not reach sandbox") - exit(1) - - check_response_status(resp) - tell_user(resp) - - -@sandbox.group("ebicssubscriber", help="manage EBICS subscribers") -@click.pass_context -def sandbox_ebicssubscriber(ctx): - pass - - -@sandbox_ebicssubscriber.command("create", help="Create an EBICS subscriber.") -@click.option("--host-id", help="Ebics host ID", required=True, prompt=True) -@click.option("--partner-id", help="Ebics partner ID", required=True, prompt=True) -@click.option("--user-id", help="Ebics user ID", required=True, prompt=True) -@click.pass_obj -def create_ebics_subscriber(obj, host_id, partner_id, user_id): - sandbox_base_url = obj.require_sandbox_base_url() - url = urljoin_nodrop(sandbox_base_url, "/admin/ebics/subscribers") - try: - resp = post( - url, - json=dict(hostID=host_id, partnerID=partner_id, userID=user_id), - **maybe_auth(obj) - ) - except Exception as e: - print(e) - print("Could not reach sandbox") - exit(1) - - check_response_status(resp) - - -@sandbox_ebicssubscriber.command("list", help="List EBICS subscribers.") -@click.pass_obj -def list_ebics_subscriber(obj): - sandbox_base_url = obj.require_sandbox_base_url() - url = urljoin_nodrop(sandbox_base_url, "/admin/ebics/subscribers") - try: - resp = get(url, **maybe_auth(obj)) - except Exception as e: - print(e) - print("Could not reach sandbox") - exit(1) - - check_response_status(resp) - tell_user(resp) - - -@sandbox.group("ebicsbankaccount", help="manage EBICS bank accounts") -@click.pass_context -def sandbox_ebicsbankaccount(ctx): - pass - - -@sandbox_ebicsbankaccount.command( - "create", - help="Create a bank account for an existing EBICS subscriber. This operation is deprecated because it doesn't associate any user profile to the bank account being created." -) -@click.option("--iban", help="IBAN", required=True) -@click.option("--bic", help="BIC", required=True) -@click.option("--person-name", help="bank account owner name", required=True) -@click.option("--account-name", help="label of this bank account", required=True) -@click.option("--ebics-user-id", help="user ID of the Ebics subscriber", required=True) -@click.option("--ebics-host-id", help="host ID of the Ebics subscriber", required=True) -@click.option( - "--ebics-partner-id", help="partner ID of the Ebics subscriber", required=True -) -@click.pass_obj -def associate_bank_account( - obj, - iban, - bic, - person_name, - account_name, - ebics_user_id, - ebics_host_id, - ebics_partner_id, -): - sandbox_base_url = obj.require_sandbox_base_url() - url = urljoin_nodrop(sandbox_base_url, "/admin/ebics/bank-accounts") - body = dict( - subscriber=dict( - userID=ebics_user_id, partnerID=ebics_partner_id, hostID=ebics_host_id - ), - iban=iban, - bic=bic, - name=person_name, - label=account_name, - ) - - try: - resp = post( - url, json=body, - **maybe_auth(obj) - ) - except Exception as e: - print(e) - print("Could not reach sandbox") - exit(1) - - check_response_status(resp) - - -@sandbox.group("bankaccount", help="manage bank accounts") -@click.pass_context -def sandbox_bankaccount(ctx): - pass - - -# This group deals with the new Access API -# and the 'demobank' model. -@sandbox.group( - "demobank", - help="Subcommands for the 'demobank' model and the Access API." -) -@click.option( - "--demobank-name", - help="Defaults to 'default'", - required=False, - default="default" - ) -@click.pass_context -def sandbox_demobank(ctx, demobank_name): - ctx.obj.demobank_name = demobank_name - pass - -@sandbox_demobank.command("list-transactions", help="List transactions.") -@click.option( - "--bank-account", - help="Label of the bank account to be debited for the transaction.", - required=True -) -@click.pass_obj -def sandbox_demobank_list_transactions(obj, bank_account): - url = obj.access_api_url (f"/accounts/{bank_account}/transactions") - try: - resp = get(url, **maybe_auth(obj)) - except Exception as e: - print(e) - print("Could not reach sandbox at " + url) - exit(1) - - check_response_status(resp) - tell_user(resp) - - -@sandbox_demobank.command("new-transaction", help="Initiate a new transaction.") -@click.option( - "--bank-account", - help="Label of the bank account to be debited for the transaction.", - required=True -) -# Including the subject in the payto to match the -# payto returned by the merchant backend helper program -# to create tip reserves. -@click.option( - "--payto-with-subject", - help="Payto address including the subject as a query parameter.", - required=True -) -@click.option( - "--amount", - help="Amount to transfer, in the CUR:X.Y format.", - required=True -) -@click.pass_obj -def sandbox_demobank_new_transaction(obj, bank_account, payto_with_subject, amount): - url = obj.access_api_url (f"/accounts/{bank_account}/transactions") - try: - body = dict(paytoUri=payto_with_subject, amount=amount) - resp = post( - url, - json=body, - **maybe_auth(obj) - ) - except Exception as e: - print(e) - print("Could not reach sandbox at " + url) - exit(1) - - check_response_status(resp) - -@sandbox_demobank.command("info", help="Return basic information of a bank account") -@click.option( - "--bank-account", - help="Label of the bank account whose information should be returned.", - required=True -) -@click.pass_obj -def sandbox_demobank_info(obj, bank_account): - url = obj.access_api_url (f"/accounts/{bank_account}") - try: - resp = get(url, **maybe_auth(obj)) - except Exception as e: - print(e) - print("Could not reach sandbox") - exit(1) - - check_response_status(resp) - tell_user(resp) - -@sandbox_demobank.command( - "debug-url", - help="Prints the base URL for the demobank to address, according to the related values passed via the environment or the command line." -) -@click.pass_obj -def debug_url(obj): - print("demobank URL", obj.demobank_base_url()) - print("access API registration URL", obj.access_api_url("/testing/register")) - -@sandbox_demobank.command("delete", - help="""delete bank account""" -) -@click.option( - "--bank-account", - help="Label of the bank account to delete.", - required=True -) -@click.pass_obj -def sandbox_demobank_delete(obj, bank_account): - url = obj.access_api_url (f"/accounts/{bank_account}") - try: - resp = delete(url, **maybe_auth(obj)) - except Exception as e: - print(e) - print("Could not reach sandbox at " + url) - exit(1) - check_response_status(resp) - -@sandbox_demobank.command("register", - help="""register a new bank account. Credentials will be taken - from the LIBEUFIN_SANDBOX_{USERNAME, PASSWORD} env variables. Note - that the username will be both the username to login at the bank - and the bank account label""" -) -@click.option( - "--public/--no-public", - default=False, - help="Decides whether a bank account is public.", -) -@click.option( - "--name", - default="", - help="Person name", -) -@click.option( - "--iban", - help="Uses this IBAN, instead of a random one.", -) -@click.pass_obj -def sandbox_demobank_register(obj, public, name, iban): - url = obj.access_api_url ("/testing/register") - if not obj.credentials_found: - print("WARNING: registering with unset credentials in the environment!!") - req = dict(username=obj.username, password=obj.password, isPublic=public) - if name != "": - req.update(name=name) - if iban: - req.update(iban=iban) - try: - resp = post(url, json=req) - except Exception as e: - print(e) - print("Could not reach sandbox at " + url) - exit(1) - check_response_status(resp) - -@sandbox_demobank.command("new-ebicssubscriber", - help="Associate a new Ebics subscriber to an existing bank account." -) -@click.option("--host-id", help="Ebics host ID", required=True) -@click.option("--partner-id", help="Ebics partner ID", required=True) -@click.option("--user-id", help="Ebics user ID", required=True) -@click.option( - "--bank-account", - help="Label of the bank account to associate with this Ebics subscriber", - required=True -) -@click.pass_obj -def sandbox_demobank_ebicssubscriber(obj, host_id, partner_id, user_id, bank_account): - demobank_url = obj.demobank_base_url() - url = urljoin_nodrop(demobank_url, "/ebics/subscribers") - try: - resp = post(url, - json=dict( - hostID=host_id, - partnerID=partner_id, - userID=user_id, - demobankAccountLabel=bank_account - ), - **maybe_auth(obj) - ) - except Exception as e: - print(e) - print("Could not reach sandbox") - exit(1) - check_response_status(resp) - -@sandbox_bankaccount.command("list", help="List accounts") -@click.pass_obj -def bankaccount_list(obj): - sandbox_base_url = obj.require_sandbox_base_url() - url = urljoin_nodrop(sandbox_base_url, f"/admin/bank-accounts") - try: - resp = get(url, **maybe_auth(obj)) - except Exception as e: - print(e) - print("Could not reach sandbox") - exit(1) - - check_response_status(resp) - tell_user(resp) - - -@sandbox_bankaccount.command("transactions", help="List transactions") -@click.argument("account-label") -@click.pass_obj -def transactions_list(obj, account_label): - sandbox_base_url = obj.require_sandbox_base_url() - url = urljoin_nodrop( - sandbox_base_url, f"/admin/bank-accounts/{account_label}/transactions" - ) - try: - resp = get(url, **maybe_auth(obj)) - except Exception as e: - print(e) - print("Could not reach sandbox") - exit(1) - - check_response_status(resp) - tell_user(resp) - - -@sandbox_bankaccount.command("generate-transactions", help="Generate test transactions") -@click.argument("account-label") -@click.pass_obj -def bankaccount_generate_transactions(obj, account_label): - sandbox_base_url = obj.require_sandbox_base_url() - url = urljoin_nodrop( - sandbox_base_url, - f"/admin/bank-accounts/{account_label}/generate-transactions" - ) - try: - resp = post(url, **maybe_auth(obj)) - except Exception as e: - print(e) - print("Could not reach sandbox") - exit(1) - - check_response_status(resp) - - -@sandbox_bankaccount.command(help="Book an incoming payment in the sandbox") -@click.argument("account-name") -@click.option("--debtor-iban", help="IBAN sending the payment", prompt=True) -@click.option("--debtor-bic", help="BIC sending the payment", prompt=True) -@click.option( - "--debtor-name", help="name of the person who is sending the payment", prompt=True -) -@click.option("--amount", help="amount with currency (currency:x.y)", prompt=True) -@click.option("--subject", help="payment subject", prompt=True) -@click.pass_obj -def simulate_incoming_transaction( - obj, - account_name, - debtor_iban, - debtor_bic, - debtor_name, - amount, - subject, -): - sandbox_base_url = obj.require_sandbox_base_url() - url = urljoin_nodrop( - sandbox_base_url, - f"/admin/bank-accounts/{account_name}/simulate-incoming-transaction", - ) - body = dict( - debtorIban=debtor_iban, - debtorBic=debtor_bic, - debtorName=debtor_name, - amount=amount, - subject=subject, - ) - try: - resp = post( - url, - json=body, - **maybe_auth(obj) - ) - except Exception as e: - print(e) - print("Could not reach sandbox") - exit(1) - - check_response_status(resp) - - -# The commands below request to the latest CIRCUIT API. - -@sandbox_demobank.command( - "circuit-cashout-confirm", - help="Confirm a cash-out operation. Only the author is allowed (no admin)." -) -@click.option( - "--tan", - help="TAN that authorizes the cash-out operaion.", - required=True, - prompt=True -) -@click.option( - "--uuid", - help="UUID of the cash-out operation to confirm.", - required=True, - prompt=True -) -@click.pass_obj -def circuit_cashout_confirm(obj, tan, uuid): - cashout_confirm_endpoint = obj.circuit_api_url(f"cashouts/{uuid}/confirm") - req = dict(tan=tan) - try: - resp = post( - cashout_confirm_endpoint, - json=req, - **maybe_auth(obj) - ) - except Exception as e: - print(e) - print("Could not reach the bank at " + cashout_confirm_endpoint) - exit(1) - - check_response_status(resp, 204) - - -@sandbox_demobank.command( - "circuit-cashout-abort", - help="Abort a cash-out operation. Admin and author are allowed to request." -) -@click.option( - "--uuid", - help="UUID of the cash-out operation to abort.", - required=True, - prompt=True -) -@click.pass_obj -def circuit_cashout_abort(obj, uuid): - cashout_abort_endpoint = obj.circuit_api_url(f"cashouts/{uuid}/abort") - try: - resp = post( - cashout_abort_endpoint, - **maybe_auth(obj) - ) - except Exception as e: - print(e) - print("Could not reach the bank at " + cashout_abort_endpoint) - exit(1) - - check_response_status(resp, 204) - -@sandbox_demobank.command( - "circuit-cashout-details", - help="Retrieve status information about one cash-out operation. Admin and author are allowed to request." -) -@click.option( - "--uuid", - help="UUID of the cash-out operation to retrieve.", - required=True, - prompt=True -) -@click.pass_obj -def circuit_cashout_info(obj, uuid): - cashout_info_endpoint = obj.circuit_api_url(f"cashouts/{uuid}") - try: - resp = get( - cashout_info_endpoint, - **maybe_auth(obj) - ) - except Exception as e: - print(e) - print("Could not reach the bank at " + cashout_info_endpoint) - exit(1) - - check_response_status(resp) - tell_user(resp) - -@sandbox_demobank.command( - "circuit-delete-account", - help="Delete one account. Only available to the administrator and for accounts with zero balance." -) -@click.option( - "--username", - help="account to delete", - required=True, - prompt=True -) -@click.pass_obj -def circuit_delete(obj, username): - - # Check that admin wasn't specified. - # Note: even if 'admin' gets through here, - # the bank can't delete it because its profile - # doesn't get a ordinary entry into the database. - if username == "admin": - print("Won't delete 'admin'", file=sys.stderr) - exit(1) - - # Do not check credentials to let the --no-auth case - # function, in case the bank allows it. - account_deletion_endpoint = obj.circuit_api_url(f"accounts/{username}") - try: - resp = delete( - account_deletion_endpoint, - **maybe_auth(obj) - ) - except Exception as e: - print(e) - print("Could not reach sandbox at " + account_deletion_endpoint) - exit(1) - - check_response_status(resp, expected_status_code=204) - - -@sandbox_demobank.command( - "circuit-register", - help="Register a new account with cash-out capabilities. It needs administrator credentials, and the new account password exported in LIBEUFIN_NEW_CIRCUIT_ACCOUNT_PASSWORD." -) -@click.option( - "--username", - help="new account username", - required=True, - prompt=True -) -@click.option( - "--cashout-address", - help="Payto address where to send fiat payments on cash-outs", - required=True, - prompt=True -) -@click.option( - "--name", - help="Legal name associated to the account.", - required=True, - prompt=True -) -@click.option( - "--phone", - help="SMS where to send the cash-out TAN.", -) -@click.option( - "--email", - help="E-mail address where to send the cash-out TAN.", -) -@click.option( - "--internal-iban", - help="Which IBAN to associate to this account. The IBAN participates only in the local currency circuit. If missing, the bank generates one.", -) -@click.pass_obj -def circuit_register( - obj, - username, - cashout_address, - name, - phone, - email, - internal_iban -): - # Check admin is requesting. - if (obj.username != "admin"): - print("Not running as 'admin'. Won't request", file=sys.stderr) - exit(1) - new_account_password = os.environ.get("LIBEUFIN_NEW_CIRCUIT_ACCOUNT_PASSWORD") - # Check that the new account password got - # exported into the environment. - if not new_account_password: - print("LIBEUFIN_NEW_CIRCUIT_ACCOUNT_PASSWORD not found in the environment", file=sys.stderr) - exit(1) - - # Get the bank base URL. - registration_endpoint = obj.circuit_api_url("accounts") - - contact_data = dict() - if (phone): - contact_data.update(phone=phone) - if (email): - contact_data.update(email=email) - req = dict( - contact_data=contact_data, - username=username, - password=new_account_password, - name=name, - cashout_address=cashout_address - ) - if internal_iban: - req.update(internal_iban=internal_iban) - try: - resp = post( - registration_endpoint, - json=req, - **maybe_auth(obj) - ) - except Exception as e: - print(e) - print("Could not reach sandbox at " + registration_endpoint) - exit(1) - - check_response_status(resp, expected_status_code=204) - - -@sandbox_demobank.command( - "circuit-reconfig", - help="Reconfigure an account with cash-out capabilities. It needs administrator or owner credentials" -) -@click.option( - "--phone", - help="Phone number for the SMS TAN", -) -@click.option( - "--email", - help="E-mail address for receiving the TAN", -) -@click.option( - "--cashout-address", - help="Payto address where to send fiat payments on cash-outs", - required=True, - prompt=True -) -@click.option( - "--username", - help="Username associated with the account to reconfigure. It defaults to LIBEUFIN_SANDBOX_USERNAME and doesn't accept 'admin'.", -) -@click.pass_obj -def circuit_reconfig( - obj, - phone, - email, - cashout_address, - username -): - resource_name = get_account_name(username, obj.username) - if not resource_name: - print("Could not find any username to reconfigure.", file=sys.stderr) - reconfig_endpoint = obj.circuit_api_url(f"accounts/{resource_name}") - contact_data = dict() - if (phone): - contact_data.update(phone=phone) - if (email): - contact_data.update(email=email) - req = dict(contact_data=contact_data, cashout_address=cashout_address) - - try: - resp = patch( - reconfig_endpoint, - json=req, - **maybe_auth(obj) - ) - except Exception as e: - print(e) - print("Could not reach sandbox at " + reconfig_endpoint) - exit(1) - - check_response_status(resp, expected_status_code=204) - - -@sandbox_demobank.command( - "circuit-password-reconfig", - help="Ask interactively to change the password. It needs administrator or owner credentials" -) -@click.option( - "--username", - help="Username whose password will change. Defaults to LIBEUFIN_SANDBOX_USERNAME and doesn't accept 'admin' as a value.", - required=False -) -@click.pass_obj -def password_reconfig(obj, username): - resource_name = get_account_name(username, obj.username) - if not resource_name: - print( - "Couldn't find the username whose password should change.", - file=sys.stderr - ) - exit(1) - print(f"Change password for account: {resource_name}.") - new_password = click.prompt( - "Enter the new password", - hide_input=True, - type=str - ) - confirm_new_password = click.prompt( - "Enter the new password again", - hide_input=True, - type=str - ) - if (new_password != confirm_new_password): - print("The password entered the second time didn't match.", file=sys.stderr) - exit(1) - password_reconfig_endpoint = obj.circuit_api_url(f"accounts/{resource_name}/auth") - req = dict(new_password=confirm_new_password) - try: - resp = patch( - password_reconfig_endpoint, - json=req, - **maybe_auth(obj) - ) - except Exception as e: - print(e) - print("Could not reach sandbox at " + password_reconfig_endpoint) - exit(1) - - check_response_status(resp, expected_status_code=204) - - -@sandbox_demobank.command( - "circuit-cashout", - help="Create a cash-out operation. If successful, the user gets a TAN." -) -@click.option( - "--subject", - help="Payment subject to associate to the outgoing and incoming payments that are associated with this cash-out operation.", - required=False -) -@click.option( - "--amount-debit", - help="Amount that will debited to the local currency account, in the <currency>:X.Y format.", - required=True, - prompt=True -) -@click.option( - "--amount-credit", - help="Amount that will credited to the fiat currency account, in the <currency>:X.Y format.", - required=True, - prompt=True -) -@click.option( - "--tan-channel", - help="Indicates how to send the TAN to the user: 'sms', 'email' and 'file' are valid values. If missing, the bank defaults to SMS. 'file' makes the server write the TAN to /tmp/libeufin-cashout-tan.txt, normally used for testing.", - required=False, -) -@click.pass_obj -def circuit_cashout(obj, subject, amount_debit, amount_credit, tan_channel): - req = dict( - amount_debit=amount_debit, - amount_credit=amount_credit - ) - if subject: - req.update(subject=subject) - if tan_channel: - req.update(tan_channel=tan_channel) - cashout_creation_endpoint = obj.circuit_api_url("cashouts") - try: - resp = post( - cashout_creation_endpoint, - json=req, - **maybe_auth(obj) - ) - except Exception as e: - print(e) - print("Could not reach sandbox at " + cashout_creation_endpoint) - exit(1) - - check_response_status(resp, expected_status_code=202) - tell_user(resp) # Communicates back the operation UUID. - -@sandbox_demobank.command( - "circuit-account-info", - help="Retrieve Circuit information about one account. Useful to get cash-out address and contact details." -) -@click.option( - "--username", - help="Username of the account to retrieve. It defaults to LIBEUFIN_SANDBOX_USERNAME and doesn't accept 'admin'.", -) -@click.pass_obj -def circuit_account_info(obj, username): - resource_name = get_account_name(username, obj.username) - if not resource_name: - print( - "Couldn't find the username whose account is being retrieved.", - file=sys.stderr - ) - exit(1) - # resource_name != admin - account_info_endpoint = obj.circuit_api_url(f"accounts/{resource_name}") - try: - resp = get( - account_info_endpoint, - **maybe_auth(obj) - ) - except Exception as e: - print(e) - print("Could not reach the bank at " + account_info_endpoint) - exit(1) - - check_response_status(resp) - tell_user(resp) - - -@sandbox_demobank.command( - "circuit-accounts", - help="Gets the list of all the accounts managed by the Circuit. Only 'admin' allowed" -) -@click.pass_obj -def circuit_accounts(obj): - # Check admin is requesting. - if (obj.username != "admin"): - print("Not running as 'admin'. Won't request", file=sys.stderr) - exit(1) - accounts_endpoint = obj.circuit_api_url(f"accounts") - try: - resp = get( - accounts_endpoint, - **maybe_auth(obj) - ) - except Exception as e: - print(e) - print("Could not reach the bank at " + accounts_endpoint) - exit(1) - - check_response_status(resp) - tell_user(resp) - - -@sandbox_demobank.command( - "circuit-cashouts", - help="Gets the list of all the pending and confirmed cash-out operations." -) -@click.pass_obj -def circuit_cashouts(obj): - # Check admin is requesting. - if (obj.username != "admin"): - print("Not running as 'admin'. Won't request", file=sys.stderr) - exit(1) - cashouts_endpoint = obj.circuit_api_url(f"cashouts") - try: - resp = get( - cashouts_endpoint, - **maybe_auth(obj) - ) - except Exception as e: - print(e) - print("Could not reach the bank at " + cashouts_endpoint) - exit(1) - - check_response_status(resp) - tell_user(resp) - -cli() diff --git a/cli/tests/add-incoming-client.sh b/cli/tests/add-incoming-client.sh deleted file mode 100755 index 36314b74..00000000 --- a/cli/tests/add-incoming-client.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -curl -v -s \ - -XPOST \ - -H "Content-Type: application/json" \ - -d'{"amount": "MANA:3.00", "reservePub": "re:publica"}' \ - http://localhost:5001/facades/test-facade/taler-wire-gateway/admin/add-incoming diff --git a/cli/tests/circuit_test.sh b/cli/tests/circuit_test.sh deleted file mode 100755 index 971e664d..00000000 --- a/cli/tests/circuit_test.sh +++ /dev/null @@ -1,118 +0,0 @@ -#!/bin/bash - -# Tests successful cases of the CLI acting -# as the client of the Circuit API. - -set -eu - -echo TESTING THE CLI SIDE OF THE CIRCUIT API -jq --version &> /dev/null || (echo "'jq' command not found"; exit 77) -curl --version &> /dev/null || (echo "'curl' command not found"; exit 77) - -DB_PATH=/tmp/circuit-test.sqlite3 -export LIBEUFIN_SANDBOX_DB_CONNECTION=jdbc:sqlite:$DB_PATH -# NOTE: unset this variable to test the SMS or e-mail TAN. -export LIBEUFIN_CASHOUT_TEST_TAN=secret-tan - -echo -n Delete previous data.. -rm -f $DB_PATH -echo DONE -echo -n Configure the default demobank... -libeufin-sandbox config default -echo DONE -echo -n Start the bank... -export LIBEUFIN_SANDBOX_ADMIN_PASSWORD=circuit -libeufin-sandbox serve &> sandbox.log & -SANDBOX_PID=$! -trap "echo -n 'killing the bank (pid $SANDBOX_PID)...'; kill $SANDBOX_PID; wait; echo DONE" EXIT -echo DONE -echo -n Wait for the bank... -curl --max-time 2 --retry-connrefused --retry-delay 1 --retry 10 http://localhost:5000/ &> /dev/null -echo DONE -echo Ask Circuit API /config... -curl http://localhost:5000/demobanks/default/circuit-api/config &> /dev/null -echo DONE -echo -n "Register new account..." -export LIBEUFIN_SANDBOX_USERNAME=admin -export LIBEUFIN_SANDBOX_PASSWORD=circuit -export LIBEUFIN_NEW_CIRCUIT_ACCOUNT_PASSWORD=foo -./libeufin-cli \ - sandbox --sandbox-url http://localhost:5000/ \ - demobank \ - circuit-register --name eee --username www \ - --cashout-address payto://iban/FIAT --internal-iban LOCAL -echo DONE -echo -n Reconfigure account specifying a phone number.. -# Give phone number. -export LIBEUFIN_SANDBOX_USERNAME=www -export LIBEUFIN_SANDBOX_PASSWORD=foo -./libeufin-cli \ - sandbox --sandbox-url http://localhost:5000/ \ - demobank \ - circuit-reconfig --cashout-address payto://iban/WWW --phone +999 -echo DONE -echo -n Create a cash-out operation... -CASHOUT_RESP=$(./libeufin-cli \ - sandbox --sandbox-url http://localhost:5000/ \ - demobank \ - circuit-cashout --tan-channel file --amount-debit=EUR:1 --amount-credit=CHF:0.95) -echo DONE -echo -n Extract the cash-out UUID... -CASHOUT_UUID=$(echo ${CASHOUT_RESP} | jq --raw-output '.uuid') -echo DONE -echo -n Get cash-out details... -RESP=$(./libeufin-cli \ - sandbox --sandbox-url http://localhost:5000/ \ - demobank \ - circuit-cashout-details \ - --uuid $CASHOUT_UUID -) -OPERATION_STATUS=$(echo $RESP | jq --raw-output '.status') -if ! test "$OPERATION_STATUS" = "PENDING"; then - echo Unexpected cash-out operation status found: $OPERATION_STATUS - exit 1 -fi -echo DONE -echo -n Delete the cash-out operation... -RESP=$(./libeufin-cli \ - sandbox --sandbox-url http://localhost:5000/ \ - demobank \ - circuit-cashout-abort \ - --uuid $CASHOUT_UUID -) -echo DONE -echo -n Create another cash-out operation... -CASHOUT_RESP=$(./libeufin-cli \ - sandbox --sandbox-url http://localhost:5000/ \ - demobank \ - circuit-cashout --tan-channel file --amount-debit=EUR:1 --amount-credit=CHF:0.95) -CASHOUT_UUID=$(echo ${CASHOUT_RESP} | jq --raw-output '.uuid') -echo DONE -echo -n Confirm the last cash-out operation... -./libeufin-cli \ - sandbox --sandbox-url http://localhost:5000/ \ - demobank \ - circuit-cashout-confirm --uuid $CASHOUT_UUID --tan secret-tan -echo DONE -# The user now has -1 balance. Let the bank -# award EUR:1 to them, in order to bring their -# balance to zero. -echo -n Bring the account to 0 balance... -export LIBEUFIN_SANDBOX_USERNAME=admin -export LIBEUFIN_SANDBOX_PASSWORD=circuit -./libeufin-cli \ - sandbox --sandbox-url http://localhost:5000/ \ - demobank \ - new-transaction \ - --bank-account admin \ - --payto-with-subject "payto://iban/SANDBOXX/LOCAL?message=bring-to-zero" \ - --amount EUR:1 -echo DONE -echo -n Delete the account... -export LIBEUFIN_SANDBOX_USERNAME=admin -export LIBEUFIN_SANDBOX_PASSWORD=circuit -./libeufin-cli \ - sandbox --sandbox-url http://localhost:5000/ \ - demobank \ - circuit-delete-account --username www -echo DONE diff --git a/cli/tests/circuit_test_email_tan.sh b/cli/tests/circuit_test_email_tan.sh deleted file mode 100755 index e1b61d9d..00000000 --- a/cli/tests/circuit_test_email_tan.sh +++ /dev/null @@ -1,83 +0,0 @@ -#!/bin/bash - -# Tests successful cases of the CLI acting -# as the client of the Circuit API. - -set -eu - -echo TESTING THE EMAIL TAN -jq --version &> /dev/null || (echo "'jq' command not found"; exit 77) -curl --version &> /dev/null || (echo "'curl' command not found"; exit 77) - -DB_PATH=/tmp/circuit-test.sqlite3 -export LIBEUFIN_SANDBOX_DB_CONNECTION=jdbc:sqlite:$DB_PATH - -echo -n Delete previous data.. -rm -f $DB_PATH -echo DONE -echo -n Configure the default demobank... -libeufin-sandbox config default -echo DONE -echo -n Starting the bank passing the e-mail TAN option... -export LIBEUFIN_SANDBOX_ADMIN_PASSWORD=circuit -libeufin-sandbox serve \ - --email-tan "../../contrib/libeufin-tan-email.sh" &> sandbox.log & -SANDBOX_PID=$! -# Cleaner: -trap "echo -n 'killing the bank (pid $SANDBOX_PID)...'; kill $SANDBOX_PID; wait; echo DONE" EXIT -echo DONE -echo -n Wait for the bank... -curl --max-time 2 --retry-connrefused --retry-delay 1 --retry 10 http://localhost:5000/ &> /dev/null -echo DONE -echo Ask Circuit API /config... -curl http://localhost:5000/demobanks/default/circuit-api/config &> /dev/null -echo DONE -echo -n "Register new account..." -export LIBEUFIN_SANDBOX_USERNAME=admin -export LIBEUFIN_SANDBOX_PASSWORD=circuit -export LIBEUFIN_NEW_CIRCUIT_ACCOUNT_PASSWORD=foo -./libeufin-cli \ - sandbox --sandbox-url http://localhost:5000/ \ - demobank \ - circuit-register --name eee --username www --email $LIBEUFIN_EMAIL_ADDRESS \ - --cashout-address payto://iban/FIAT --internal-iban LOCAL -echo DONE -echo -n Create the cash-out operation with the e-mail TAN... -export LIBEUFIN_SANDBOX_USERNAME=www -export LIBEUFIN_SANDBOX_PASSWORD=foo -CASHOUT_RESP=$(./libeufin-cli \ - sandbox --sandbox-url http://localhost:5000/ \ - demobank \ - circuit-cashout \ - --tan-channel=email \ - --amount-debit=EUR:1 \ - --amount-credit=CHF:0.95 -) -CASHOUT_UUID=$(echo ${CASHOUT_RESP} | jq --raw-output '.uuid') -echo DONE -echo -n Checking that cash-out status is 'pending'... -RESP=$(./libeufin-cli \ - sandbox --sandbox-url http://localhost:5000/ \ - demobank \ - circuit-cashout-details \ - --uuid $CASHOUT_UUID -) -OPERATION_STATUS=$(echo $RESP | jq --raw-output '.status') -if ! test "$OPERATION_STATUS" = "PENDING"; then - echo Unexpected cash-out operation status found: $OPERATION_STATUS - exit 1 -fi -echo DONE -read -p "Enter the TAN received via e-mail:" INPUT_TAN -echo -n Confirming the last cash-out operation... -./libeufin-cli \ - sandbox --sandbox-url http://localhost:5000/ \ - demobank \ - circuit-cashout-confirm --uuid $CASHOUT_UUID --tan $INPUT_TAN -echo DONE -echo -n Checking the balance... -RESP=$(libeufin-cli sandbox --sandbox-url http://localhost:5000/ demobank info --bank-account www) -BALANCE=$(echo $RESP | jq -r '.balance.amount') -INDICATOR=$(echo $RESP | jq -r '.balance.credit_debit_indicator') -echo $BALANCE $INDICATOR -echo DONE diff --git a/cli/tests/circuit_test_file_tan.sh b/cli/tests/circuit_test_file_tan.sh deleted file mode 100755 index f98a436a..00000000 --- a/cli/tests/circuit_test_file_tan.sh +++ /dev/null @@ -1,126 +0,0 @@ -#!/bin/bash - -# Tests successful cases of the CLI acting -# as the client of the Circuit API. - -set -eu - -echo TESTING THE CLI SIDE OF THE CIRCUIT API -jq --version &> /dev/null || (echo "'jq' command not found"; exit 77) -curl --version &> /dev/null || (echo "'curl' command not found"; exit 77) - -DB_PATH=/tmp/circuit-test.sqlite3 -export LIBEUFIN_SANDBOX_DB_CONNECTION=jdbc:sqlite:$DB_PATH - -echo -n Delete previous data.. -rm -f $DB_PATH -echo DONE -echo -n Configure the default demobank... -libeufin-sandbox config default -echo DONE -echo -n Start the bank... -export LIBEUFIN_SANDBOX_ADMIN_PASSWORD=circuit -libeufin-sandbox serve &> sandbox.log & -SANDBOX_PID=$! -trap "echo -n 'killing the bank (pid $SANDBOX_PID)...'; kill $SANDBOX_PID; wait; echo DONE" EXIT -echo DONE -echo -n Wait for the bank... -curl --max-time 2 --retry-connrefused --retry-delay 1 --retry 10 http://localhost:5000/ &> /dev/null -echo DONE -echo Ask Circuit API /config... -curl http://localhost:5000/demobanks/default/circuit-api/config &> /dev/null -echo DONE -echo -n "Register new account..." -export LIBEUFIN_SANDBOX_USERNAME=admin -export LIBEUFIN_SANDBOX_PASSWORD=circuit -export LIBEUFIN_NEW_CIRCUIT_ACCOUNT_PASSWORD=foo -./libeufin-cli \ - sandbox --sandbox-url http://localhost:5000/ \ - demobank \ - circuit-register --name eee --username www \ - --cashout-address payto://iban/FIAT --internal-iban LOCAL -echo DONE -echo -n Reconfigure account specifying a phone number.. -# Give phone number. -export LIBEUFIN_SANDBOX_USERNAME=www -export LIBEUFIN_SANDBOX_PASSWORD=foo -./libeufin-cli \ - sandbox --sandbox-url http://localhost:5000/ \ - demobank \ - circuit-reconfig --cashout-address payto://iban/WWW --phone +999 -echo DONE -echo -n Create a cash-out operation... -CASHOUT_RESP=$(./libeufin-cli \ - sandbox --sandbox-url http://localhost:5000/ \ - demobank \ - circuit-cashout \ - --tan-channel=file \ - --amount-debit=EUR:1 \ - --amount-credit=CHF:0.95 -) -echo DONE -echo -n "Extract the cash-out UUID..." -CASHOUT_UUID=$(echo ${CASHOUT_RESP} | jq --raw-output '.uuid') -echo DONE -echo -n Get cash-out details... -RESP=$(./libeufin-cli \ - sandbox --sandbox-url http://localhost:5000/ \ - demobank \ - circuit-cashout-details \ - --uuid $CASHOUT_UUID -) -OPERATION_STATUS=$(echo $RESP | jq --raw-output '.status') -if ! test "$OPERATION_STATUS" = "PENDING"; then - echo Unexpected cash-out operation status found: $OPERATION_STATUS - exit 1 -fi -echo DONE -echo -n Abort the cash-out operation... -RESP=$(./libeufin-cli \ - sandbox --sandbox-url http://localhost:5000/ \ - demobank \ - circuit-cashout-abort \ - --uuid $CASHOUT_UUID -) -echo DONE -echo -n Create another cash-out operation... -CASHOUT_RESP=$(./libeufin-cli \ - sandbox --sandbox-url http://localhost:5000/ \ - demobank \ - circuit-cashout \ - --tan-channel=file \ - --amount-debit=EUR:1 \ - --amount-credit=CHF:0.95 -) -CASHOUT_UUID=$(echo ${CASHOUT_RESP} | jq --raw-output '.uuid') -echo DONE -echo Reading the TAN from /tmp/libeufin-cashout-tan.txt -INPUT_TAN=$(cat /tmp/libeufin-cashout-tan.txt) -echo -n Confirm the last cash-out operation... -./libeufin-cli \ - sandbox --sandbox-url http://localhost:5000/ \ - demobank \ - circuit-cashout-confirm --uuid $CASHOUT_UUID --tan $INPUT_TAN -echo DONE -# The user now has -1 balance. Let the bank -# award EUR:1 to them, in order to bring their -# balance to zero. -echo -n Bring the account to 0 balance... -export LIBEUFIN_SANDBOX_USERNAME=admin -export LIBEUFIN_SANDBOX_PASSWORD=circuit -./libeufin-cli \ - sandbox --sandbox-url http://localhost:5000/ \ - demobank \ - new-transaction \ - --bank-account admin \ - --payto-with-subject "payto://iban/SANDBOXX/LOCAL?message=bring-to-zero" \ - --amount EUR:1 -echo DONE -echo -n Delete the account... -export LIBEUFIN_SANDBOX_USERNAME=admin -export LIBEUFIN_SANDBOX_PASSWORD=circuit -./libeufin-cli \ - sandbox --sandbox-url http://localhost:5000/ \ - demobank \ - circuit-delete-account --username www -echo DONE diff --git a/cli/tests/debit_test.sh b/cli/tests/debit_test.sh deleted file mode 100755 index 9e1ad97e..00000000 --- a/cli/tests/debit_test.sh +++ /dev/null @@ -1,77 +0,0 @@ -#!/bin/bash - -# Tests successful cases of the CLI acting -# as the client of the Circuit API. - -set -eu - -echo TESTING DEBIT THRESHOLD -jq --version &> /dev/null || (echo "'jq' command not found"; exit 77) -curl --version &> /dev/null || (echo "'curl' command not found"; exit 77) - -DB_PATH=/tmp/debit-test.sqlite3 -export LIBEUFIN_SANDBOX_DB_CONNECTION=jdbc:sqlite:$DB_PATH - -echo -n Delete previous data.. -rm -f $DB_PATH -echo DONE -echo -n Configure the default demobank, with users limit 0... -libeufin-sandbox config --currency MANA default --users-debt-limit=0 -echo DONE -echo -n Start the bank... -export LIBEUFIN_SANDBOX_ADMIN_PASSWORD=circuit -libeufin-sandbox serve &> sandbox.log & -SANDBOX_PID=$! -trap "echo -n 'killing the bank (pid $SANDBOX_PID)...'; kill $SANDBOX_PID; wait; echo DONE" EXIT -echo DONE -echo -n Wait for the bank... -curl --max-time 2 --retry-connrefused --retry-delay 1 --retry 10 http://localhost:5000/ &> /dev/null -echo DONE - -echo -n "Register new account..." -export LIBEUFIN_SANDBOX_USERNAME=www -export LIBEUFIN_SANDBOX_PASSWORD=foo - -./libeufin-cli \ - sandbox --sandbox-url http://localhost:5000/ \ - demobank \ - register -echo DONE -echo -n "Get the admin's IBAN..." -ADMIN_IBAN=$(echo "SELECT iban FROM BankAccounts WHERE label='admin'" | sqlite3 $DB_PATH) -echo "DONE ($ADMIN_IBAN)" -echo -n "Try to surpass the debit threshold (user pays admin)..." -./libeufin-cli \ - sandbox --sandbox-url http://localhost:5000/ \ - demobank \ - new-transaction \ - --bank-account www \ - --payto-with-subject "payto://iban/SANDBOXX/${ADMIN_IBAN}?message=go-debit" \ - --amount MANA:99999 &> /dev/null || true -echo DONE - -echo -n Check the amount is still the initial zero... -RESP=$(libeufin-cli sandbox --sandbox-url http://localhost:5000/ demobank info --bank-account www) -BALANCE=$(echo $RESP | jq -r '.balance.amount') -if [ "$BALANCE" != "MANA:0" ]; then - echo Debit threshold of MANA:0 not respected. - exit 1 -fi -echo DONE - -echo -n "Try to surpass the debit threshold via low-level libeufin-sandbox command..." -libeufin-sandbox \ - make-transaction \ - --credit-account=admin \ - --debit-account=www \ - MANA:9999 "Go debit again." &> /dev/null || true -echo DONE - -echo -n Check the amount is still the initial zero... -RESP=$(libeufin-cli sandbox --sandbox-url http://localhost:5000/ demobank info --bank-account www) -BALANCE=$(echo $RESP | jq -r '.balance.amount') -if [ "$BALANCE" != "MANA:0" ]; then - echo Debit threshold of MANA:0 not respected via low-level libeufin-sandbox command. - exit 1 -fi -echo DONE diff --git a/cli/tests/launch_services_with_ebics.sh b/cli/tests/launch_services_with_ebics.sh deleted file mode 100755 index fdd5a74d..00000000 --- a/cli/tests/launch_services_with_ebics.sh +++ /dev/null @@ -1,106 +0,0 @@ -#!/bin/bash - -# Convenience script to setup and run a Sandbox + Nexus -# EBICS pair, in order to try CLI commands. -set -eu - -function exit_cleanup() -{ - echo "Running exit-cleanup" - for n in `jobs -p` - do - kill $n 2> /dev/null || true - done - wait || true - echo "DONE" -} - -trap "exit_cleanup" EXIT -echo RUNNING SANDBOX-NEXUS EBICS PAIR -jq --version &> /dev/null || (echo "'jq' command not found"; exit 77) -curl --version &> /dev/null || (echo "'curl' command not found"; exit 77) - -DB_PATH=/tmp/libeufin-cli-test.sqlite3 -export LIBEUFIN_SANDBOX_DB_CONNECTION=jdbc:sqlite:$DB_PATH - -echo -n Delete previous data... -rm -f $DB_PATH -echo DONE -echo -n Configure the default demobank with MANA... -libeufin-sandbox config --with-signup-bonus --currency MANA default -echo DONE -echo -n Start the bank... -export LIBEUFIN_SANDBOX_ADMIN_PASSWORD=foo -libeufin-sandbox serve &> sandbox.log & -SANDBOX_PID=$! -echo DONE -echo -n Wait for the bank... -curl --max-time 2 --retry-connrefused --retry-delay 1 --retry 10 http://localhost:5000/ &> /dev/null -echo DONE -echo -n Make one superuser at Nexus... -export LIBEUFIN_NEXUS_DB_CONNECTION=jdbc:sqlite:$DB_PATH -libeufin-nexus superuser test-user --password x -echo DONE -echo -n Launching Nexus... -libeufin-nexus serve &> nexus.log & -NEXUS_PID=$! -echo DONE -echo -n Waiting for Nexus... -curl --max-time 2 --retry-connrefused --retry-delay 1 --retry 10 http://localhost:5001/ &> /dev/null -echo DONE - -echo -n "Register the 'www' Sandbox account..." -export LIBEUFIN_SANDBOX_USERNAME=www -export LIBEUFIN_SANDBOX_PASSWORD=foo -libeufin-cli \ - sandbox --sandbox-url http://localhost:5000/ \ - demobank \ - register -echo DONE -export LIBEUFIN_SANDBOX_USERNAME=admin -export LIBEUFIN_SANDBOX_PASSWORD=foo -echo -n "Create EBICS host at Sandbox..." -libeufin-cli sandbox \ - --sandbox-url http://localhost:5000 \ - ebicshost create --host-id wwwebics -echo OK -echo -n "Create 'www' EBICS subscriber at Sandbox..." -libeufin-cli sandbox \ - --sandbox-url http://localhost:5000 \ - demobank new-ebicssubscriber --host-id wwwebics \ - --user-id wwwebics --partner-id wwwpartner \ - --bank-account www # that's a username _and_ a bank account name -echo OK -export LIBEUFIN_NEXUS_USERNAME=test-user -export LIBEUFIN_NEXUS_PASSWORD=x -export LIBEUFIN_NEXUS_URL=http://localhost:5001 -echo -n Creating the EBICS connection at Nexus... -libeufin-cli connections new-ebics-connection \ - --ebics-url "http://localhost:5000/ebicsweb" \ - --host-id wwwebics \ - --partner-id wwwpartner \ - --ebics-user-id wwwebics \ - wwwconn -echo DONE -echo -n Setup EBICS keying... -libeufin-cli connections connect wwwconn > /dev/null -echo OK -echo -n Download bank account name from Sandbox... -libeufin-cli connections download-bank-accounts wwwconn -echo OK -echo -n Importing bank account info into Nexus... -libeufin-cli connections import-bank-account \ - --offered-account-id www \ - --nexus-bank-account-id www-nexus \ - wwwconn -echo OK -echo -n Create the Taler facade at Nexus... -libeufin-cli facades \ - new-taler-wire-gateway-facade \ - --currency TESTKUDOS --facade-name test-facade \ - wwwconn www-nexus -echo OK -echo -n "Ticking, to let statements be generated..." -libeufin-sandbox camt053tick -echo OK -read -p "Press Enter to terminate..." diff --git a/cli/tests/launch_services_with_xlibeufinbank.sh b/cli/tests/launch_services_with_xlibeufinbank.sh deleted file mode 100755 index 228b372b..00000000 --- a/cli/tests/launch_services_with_xlibeufinbank.sh +++ /dev/null @@ -1,118 +0,0 @@ -#!/bin/bash - -# Convenience script to setup and run a Sandbox & Nexus -# connected through x-libeufin-bank. -set -eu - -# WITH_TASKS=1 -WITH_TASKS=0 -function exit_cleanup() -{ - echo "Running exit-cleanup" - for n in `jobs -p` - do - kill $n 2> /dev/null || true - done - wait || true - echo "DONE" -} - -trap "exit_cleanup" EXIT -echo RUNNING SANDBOX-NEXUS EBICS PAIR -jq --version &> /dev/null || (echo "'jq' command not found"; exit 77) -curl --version &> /dev/null || (echo "'curl' command not found"; exit 77) - -DB_CONN="postgresql:///libeufincheck" -export LIBEUFIN_SANDBOX_DB_CONNECTION=$DB_CONN -export LIBEUFIN_NEXUS_DB_CONNECTION=$DB_CONN - -echo -n Delete previous data... -libeufin-sandbox reset-tables -libeufin-nexus reset-tables -echo DONE -echo -n Configure the default demobank with MANA... -libeufin-sandbox config --with-signup-bonus --currency MANA default -echo DONE -echo -n Setting the default exchange at Sandbox... -libeufin-sandbox \ - default-exchange \ - "https://exchange.example.com/" \ - "payto://iban/NOTUSED" -echo DONE -echo -n Start the bank... -export LIBEUFIN_SANDBOX_ADMIN_PASSWORD=foo -libeufin-sandbox serve > sandbox.log 2>&1 & -SANDBOX_PID=$! -echo DONE -echo -n Wait for the bank... -curl --max-time 4 --retry-all-errors --retry-connrefused --retry-delay 1 --retry 10 http://localhost:5000/ &> /dev/null -echo DONE -echo -n Make one superuser at Nexus... -libeufin-nexus superuser test-user --password x -echo DONE -echo -n Launching Nexus... -libeufin-nexus serve &> nexus.log & -NEXUS_PID=$! -echo DONE -echo -n Waiting for Nexus... -curl --max-time 4 --retry-all-errors --retry-connrefused --retry-delay 1 --retry 10 http://localhost:5001/ &> /dev/null -echo DONE - -echo -n "Register the Sandbox account..." -export LIBEUFIN_SANDBOX_USERNAME=sandbox-user -export LIBEUFIN_SANDBOX_PASSWORD=foo -libeufin-cli \ - sandbox --sandbox-url http://localhost:5000/ \ - demobank \ - register -echo DONE -echo -n Creating the x-libeufin-bank connection at Nexus... -export LIBEUFIN_NEXUS_USERNAME=test-user -export LIBEUFIN_NEXUS_PASSWORD=x -export LIBEUFIN_NEXUS_URL=http://localhost:5001 -# echoing the password to STDIN, as that is a "prompt" option. -libeufin-cli connections new-xlibeufinbank-connection \ - --bank-url "http://localhost:5000/demobanks/default/access-api" \ - --username sandbox-user \ - --password foo \ - wwwconn -echo DONE -echo -n Connecting the x-libeufin-bank connection... -libeufin-cli connections connect wwwconn -echo DONE -# Importing the bank account under a local name at Nexus. -echo -n Importing the x-libeufin-bank account locally.. -libeufin-cli connections import-bank-account \ - --offered-account-id sandbox-user \ - --nexus-bank-account-id foo-at-nexus wwwconn -echo DONE -echo -n Create the Taler facade at Nexus... -libeufin-cli facades \ - new-taler-wire-gateway-facade \ - --currency TESTKUDOS --facade-name test-facade \ - wwwconn foo-at-nexus -echo DONE -if test 1 = $WITH_TASKS; then - echo -n Creating submit transactions task.. - libeufin-cli accounts task-schedule \ - --task-type submit \ - --task-name www-payments \ - --task-cronspec "* * *" \ - foo-at-nexus || true - # Tries every second. Ask C52 - echo DONE - echo -n Creating fetch transactions task.. - # Not idempotent, FIXME #7739 - libeufin-cli accounts task-schedule \ - --task-type fetch \ - --task-name www-history \ - --task-cronspec "* * *" \ - --task-param-level statement \ - --task-param-range-type since-last \ - foo-at-nexus || true - echo DONE -else - echo NOT creating background tasks! -fi - -read -p "Press Enter to terminate..." diff --git a/cli/tests/libeufin-cli b/cli/tests/libeufin-cli deleted file mode 120000 index c69a3d87..00000000 --- a/cli/tests/libeufin-cli +++ /dev/null @@ -1 +0,0 @@ -../bin/libeufin-cli
\ No newline at end of file diff --git a/cli/tests/registration_test.sh b/cli/tests/registration_test.sh deleted file mode 100755 index 0e561cbc..00000000 --- a/cli/tests/registration_test.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/bash - -# Tests successful cases of the CLI acting -# as the client of the Circuit API. - -set -eu - -echo TESTING ACCESS API REGISTRATION -jq --version &> /dev/null || (echo "'jq' command not found"; exit 77) -curl --version &> /dev/null || (echo "'curl' command not found"; exit 77) - -DB_PATH=/tmp/registration-test.sqlite3 -export LIBEUFIN_SANDBOX_DB_CONNECTION=jdbc:sqlite:$DB_PATH - -echo -n Delete previous data.. -rm -f $DB_PATH -echo DONE -echo -n Configure the default demobank, with users limit 0... -libeufin-sandbox config default -echo DONE -echo -n Start the bank... -export LIBEUFIN_SANDBOX_ADMIN_PASSWORD=circuit -libeufin-sandbox serve &> sandbox.log & -SANDBOX_PID=$! -trap "echo -n 'killing the bank (pid $SANDBOX_PID)...'; kill $SANDBOX_PID; wait; echo DONE" EXIT -echo DONE -echo -n Wait for the bank... -curl --max-time 2 --retry-connrefused --retry-delay 1 --retry 10 http://localhost:5000/ &> /dev/null -echo DONE - -echo -n "Register new account..." -export LIBEUFIN_SANDBOX_USERNAME=www -export LIBEUFIN_SANDBOX_PASSWORD=foo - -./libeufin-cli \ - sandbox --sandbox-url http://localhost:5000/ \ - demobank \ - register -echo DONE - -echo -n Check the account is found... -curl -u "www:foo" http://localhost:5000/demobanks/default/access-api/accounts/www -echo DONE diff --git a/cli/tests/twg-history-loop.sh b/cli/tests/twg-history-loop.sh deleted file mode 100755 index eafff9e1..00000000 --- a/cli/tests/twg-history-loop.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -set -exu - -HOWMANY_SECONDS=30 -NO_LONG_POLL=0 - -if test $NO_LONG_POLL = 1; then - echo "Requesting Taler history WITHOUT any long-poll in infinite loop..." - while true; do - curl -u test-user:x \ - "http://localhost:5001/facades/test-facade/taler-wire-gateway/history/incoming?delta=5" - done - exit -fi - -echo "Requesting Taler history with $HOWMANY_SECONDS second(s) timeout in infinite loop..." -while true; do - curl -v -u test-user:x \ - "http://localhost:5001/facades/test-facade/taler-wire-gateway/history/incoming?delta=5&long_poll_ms=${HOWMANY_SECONDS}000" -done diff --git a/cli/tests/wire-transfer.sh b/cli/tests/wire-transfer.sh deleted file mode 100755 index ce0526c6..00000000 --- a/cli/tests/wire-transfer.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -set -eux - -# Pays the www Sandbox user, using one reserve pub -# as the subject -- _in case_ Taler is being tested. -RESERVE_PUB=$(gnunet-ecc -g1 /tmp/www &> /dev/null && gnunet-ecc -p /tmp/www) -# Must match the one from launch_services.sh -export LIBEUFIN_SANDBOX_DB_CONNECTION="jdbc:postgresql://localhost:5432/libeufincheck?user=$(whoami)" -libeufin-sandbox \ - make-transaction \ - --credit-account=sandbox-user \ - --debit-account=admin MANA:2 \ - $RESERVE_PUB diff --git a/cli/tests/wirewatch.conf b/cli/tests/wirewatch.conf deleted file mode 100644 index c9587441..00000000 --- a/cli/tests/wirewatch.conf +++ /dev/null @@ -1,11 +0,0 @@ -[exchange-accountcredentials-1] -WIRE_GATEWAY_URL = "http://localhost:5001/accounts/test-user/taler-wire-gateway/" -WIRE_GATEWAY_AUTH_METHOD = basic -USERNAME = test-user -PASSWORD = x - -[exchange-account-1] -# What is the account URL? -PAYTO_URI = "payto://iban/NOTUSED" -ENABLE_DEBIT = YES -ENABLE_CREDIT = YES |