aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2023-10-06 02:11:55 +0200
committerFlorian Dold <florian@dold.me>2023-10-06 02:11:55 +0200
commita2e6825908e6fb0271bbc58d849fd6480d013316 (patch)
treeb4e54c1e4fa3500c1dc144f7676e5470d8f03e6b
parent80a518748cc74cabe52d96b59022ab5792aa815a (diff)
downloadlibeufin-a2e6825908e6fb0271bbc58d849fd6480d013316.tar.gz
libeufin-a2e6825908e6fb0271bbc58d849fd6480d013316.tar.bz2
libeufin-a2e6825908e6fb0271bbc58d849fd6480d013316.zip
cleanup
-rw-r--r--build.gradle35
-rwxr-xr-xcli/bin/libeufin-cli2004
-rwxr-xr-xcli/tests/add-incoming-client.sh7
-rwxr-xr-xcli/tests/circuit_test.sh118
-rwxr-xr-xcli/tests/circuit_test_email_tan.sh83
-rwxr-xr-xcli/tests/circuit_test_file_tan.sh126
-rwxr-xr-xcli/tests/debit_test.sh77
-rwxr-xr-xcli/tests/launch_services_with_ebics.sh106
-rwxr-xr-xcli/tests/launch_services_with_xlibeufinbank.sh118
l---------cli/tests/libeufin-cli1
-rwxr-xr-xcli/tests/registration_test.sh43
-rwxr-xr-xcli/tests/twg-history-loop.sh21
-rwxr-xr-xcli/tests/wire-transfer.sh14
-rw-r--r--cli/tests/wirewatch.conf11
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