gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[libeufin] branch master updated: CLI side of the Circuit API.


From: gnunet
Subject: [libeufin] branch master updated: CLI side of the Circuit API.
Date: Wed, 04 Jan 2023 14:32:34 +0100

This is an automated email from the git hooks/post-receive script.

ms pushed a commit to branch master
in repository libeufin.

The following commit(s) were added to refs/heads/master by this push:
     new 252d91c5 CLI side of the Circuit API.
252d91c5 is described below

commit 252d91c515c6a788a547bc10b91c5fa288ef31c0
Author: MS <ms@taler.net>
AuthorDate: Wed Jan 4 14:30:33 2023 +0100

    CLI side of the Circuit API.
    
    Implement commands to register and reconfigure
    accounts, and changing their password.
---
 cli/bin/libeufin-cli | 211 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 210 insertions(+), 1 deletion(-)

diff --git a/cli/bin/libeufin-cli b/cli/bin/libeufin-cli
index 6bdd795e..0f52f915 100755
--- a/cli/bin/libeufin-cli
+++ b/cli/bin/libeufin-cli
@@ -10,10 +10,29 @@ from datetime import datetime
 import requests
 
 # FIXME: always use qualified name
-from requests import post, get, auth, delete
+from requests import post, get, auth, delete, patch
 from urllib.parse import urljoin
 from getpass import getpass
 
+# Extracts the circuit account username by processing
+# the arguments or the environment.  It gives precedence
+# to the username met on the CLI, defaulting to the environment
+# when that is missing.  Returns the username, or None if that
+# could not be found.  This function helps when a username
+# is a 'resource name'.  Namely, when such username points
+# at a customer username; therefore, the value 'admin' is not
+# accepted since that's never used in that way.
+def get_circuit_username(usernameCli, usernameEnv):
+    maybeUsername = usernameCli
+    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.
@@ -305,6 +324,11 @@ not found in the environment, assuming tests are being 
run..."""
         # 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}")
@@ -1509,4 +1533,189 @@ def simulate_incoming_transaction(
     check_response_status(resp)
 
 
+# The commands below request to the latest CIRCUIT API.
+
+@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.pass_obj
+def circuit_register(
+  obj,
+  username,
+  cashout_address,
+  name,
+  phone,
+  email
+):
+    # 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")
+
+    # Craft the request.
+
+    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
+    )
+    try:
+        resp = post(
+            registration_endpoint,
+            json=req,
+            auth=auth.HTTPBasicAuth(obj.username, obj.password)
+        )
+    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_circuit_username(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,
+            auth=auth.HTTPBasicAuth(obj.username, obj.password)
+        )
+    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_circuit_username(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,
+            auth=auth.HTTPBasicAuth(obj.username, obj.password)
+        )
+    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)
+
 cli()

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]