gnunet-svn
[Top][All Lists]
Advanced

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

[taler-anastasis] branch master updated: -note left-over todos


From: gnunet
Subject: [taler-anastasis] branch master updated: -note left-over todos
Date: Sun, 15 Aug 2021 11:53:55 +0200

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

grothoff pushed a commit to branch master
in repository anastasis.

The following commit(s) were added to refs/heads/master by this push:
     new eabd8e4  -note left-over todos
eabd8e4 is described below

commit eabd8e45715a2d2c76f8eb8a99e09981b8a1b254
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Sun Aug 15 11:53:51 2021 +0200

    -note left-over todos
---
 .../anastasis-helper-authorization-iban.c          | 343 +++++++++++++++++++++
 src/include/anastasis_service.h                    |  14 +-
 src/restclient/anastasis_api_keyshare_lookup.c     |  44 +--
 3 files changed, 381 insertions(+), 20 deletions(-)

diff --git a/src/authorization/anastasis-helper-authorization-iban.c 
b/src/authorization/anastasis-helper-authorization-iban.c
new file mode 100644
index 0000000..ce1d149
--- /dev/null
+++ b/src/authorization/anastasis-helper-authorization-iban.c
@@ -0,0 +1,343 @@
+/*
+  This file is part of Anastasis
+  Copyright (C) 2016--2021 Anastasis SARL
+
+  Anastasis is free software; you can redistribute it and/or modify it under 
the
+  terms of the GNU Affero General Public License as published by the Free 
Software
+  Foundation; either version 3, or (at your option) any later version.
+
+  Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more 
details.
+
+  You should have received a copy of the GNU Affero General Public License 
along with
+  Anastasis; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file anastasis-helper-authorization-iban.c
+ * @brief Process that watches for wire transfers to Anastasis bank account
+ * @author Christian Grothoff
+ *
+ * TODO:
+ * - blocked on #6992
+ * - needs XXX_bank_service to access new facade once #6992 is implemented
+ * - needs to load authentication information
+ * - needs to load 'last known' transaction from DB
+ */
+#include "platform.h"
+#include <gnunet/gnunet_util_lib.h>
+#include <jansson.h>
+#include <pthread.h>
+#include <microhttpd.h>
+#include <taler/taler_json_lib.h>
+#include <XXX_bank_service.h>
+#include "anastasis_db_lib.h"
+
+/**
+ * How long to wait for an HTTP reply if there
+ * are no transactions pending at the server?
+ */
+#define LONGPOLL_TIMEOUT GNUNET_TIME_UNIT_HOURS
+
+/**
+ * Authentication data needed to access the account.
+ */
+static struct BANK_AccountInfo *auth;
+
+/**
+ * Active request for history.
+ */
+static struct BANK_CreditHistoryHandle *hh;
+
+/**
+ * Handle to the context for interacting with the bank.
+ */
+static struct GNUNET_CURL_Context *ctx;
+
+/**
+ * What is the last row ID that we have already processed?
+ */
+static uint64_t latest_row_off;
+
+/**
+ * Scheduler context for running the @e ctx.
+ */
+static struct GNUNET_CURL_RescheduleContext *rc;
+
+/**
+ * The configuration (global)
+ */
+static const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+/**
+ * Our DB plugin.
+ */
+static struct ANASTASIS_DatabasePlugin *db_plugin;
+
+/**
+ * How long should we sleep when idle before trying to find more work?
+ * Useful in case bank does not support long polling.
+ */
+static struct GNUNET_TIME_Relative idle_sleep_interval;
+
+/**
+ * Value to return from main(). 0 on success, non-zero on
+ * on serious errors.
+ */
+static int global_ret;
+
+/**
+ * Current task waiting for execution, if any.
+ */
+static struct GNUNET_SCHEDULER_Task *task;
+
+
+/**
+ * We're being aborted with CTRL-C (or SIGTERM). Shut down.
+ *
+ * @param cls closure
+ */
+static void
+shutdown_task (void *cls)
+{
+  (void) cls;
+  if (NULL != hh)
+  {
+    BANK_credit_history_cancel (hh);
+    hh = NULL;
+  }
+  if (NULL != ctx)
+  {
+    GNUNET_CURL_fini (ctx);
+    ctx = NULL;
+  }
+  if (NULL != rc)
+  {
+    GNUNET_CURL_gnunet_rc_destroy (rc);
+    rc = NULL;
+  }
+  if (NULL != task)
+  {
+    GNUNET_SCHEDULER_cancel (task);
+    task = NULL;
+  }
+  ANASTASIS_DB_plugin_unload (db_plugin);
+  db_plugin = NULL;
+  cfg = NULL;
+}
+
+
+/**
+ * Query for incoming wire transfers.
+ *
+ * @param cls NULL
+ */
+static void
+find_transfers (void *cls);
+
+
+/**
+ * Callbacks of this type are used to serve the result of asking
+ * the bank for the transaction history.
+ *
+ * @param cls closure with the `struct WioreAccount *` we are processing
+ * @param http_status HTTP status code from the server
+ * @param ec taler error code
+ * @param serial_id identification of the position at which we are querying
+ * @param details details about the wire transfer
+ * @return #GNUNET_OK to continue, #GNUNET_SYSERR to abort iteration
+ */
+static int
+history_cb (void *cls,
+            unsigned int http_status,
+            enum TALER_ErrorCode ec,
+            uint64_t serial_id,
+            const struct BANK_CreditDetails *details)
+{
+  enum GNUNET_DB_QueryStatus qs;
+
+  (void) json;
+  if (NULL == details)
+  {
+    hh = NULL;
+    if (TALER_EC_NONE != ec)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Error fetching history: ec=%u, http_status=%u\n",
+                  (unsigned int) ec,
+                  http_status);
+    }
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "End of list.\n");
+    GNUNET_assert (NULL == task);
+    task = GNUNET_SCHEDULER_add_at (delayed_until,
+                                    &find_transfers,
+                                    NULL);
+    return GNUNET_OK; /* will be ignored anyway */
+  }
+  if (serial_id <= latest_row_off)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Serial ID %llu not monotonic (got %llu before). Failing!\n",
+                (unsigned long long) serial_id,
+                (unsigned long long) latest_row_off);
+    GNUNET_SCHEDULER_shutdown ();
+    hh = NULL;
+    return GNUNET_SYSERR;
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Adding wire transfer over %s with (hashed) subject `%s'\n",
+              TALER_amount2s (&details->amount),
+              details->wire_subject);
+  qs = db_plugin->record_auth_iban_payment (db_plugin->cls,
+                                            serial_id,
+                                            details->wire_subject,
+                                            &details->amount,
+                                            details->debit_account_uri,
+                                            details->credit_account_uri,
+                                            details->execution_time);
+  switch (qs)
+  {
+  case GNUNET_DB_STATUS_HARD_ERROR:
+    GNUNET_break (0);
+    GNUNET_SCHEDULER_shutdown ();
+    hh = NULL;
+    return GNUNET_SYSERR;
+  case GNUNET_DB_STATUS_SOFT_ERROR:
+    GNUNET_break (0);
+    hh = NULL;
+    return GNUNET_SYSERR;
+  case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
+    /* already existed (!?), should be impossible */
+    GNUNET_break (0);
+    hh = NULL;
+    return GNUNET_SYSERR;
+  case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
+    /* normal case */
+    break;
+  }
+  latest_row_off = serial_id;
+  return GNUNET_OK;
+}
+
+
+/**
+ * Query for incoming wire transfers.
+ *
+ * @param cls NULL
+ */
+static void
+find_transfers (void *cls)
+{
+  enum GNUNET_DB_QueryStatus qs;
+
+  (void) cls;
+  task = NULL;
+  GNUNET_assert (NULL == hh);
+  hh = BANK_credit_history (ctx,
+                            &auth,
+                            latest_row_off,
+                            1024,
+                            test_mode
+                            ? GNUNET_TIME_UNIT_ZERO
+                            : LONGPOLL_TIMEOUT,
+                            &history_cb,
+                            NULL);
+  if (NULL == hh)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to start request for account history!\n");
+    global_ret = EXIT_FAILURE;
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+}
+
+
+/**
+ * First task.
+ *
+ * @param cls closure, NULL
+ * @param args remaining command-line arguments
+ * @param cfgfile name of the configuration file used (for saving, can be 
NULL!)
+ * @param c configuration
+ */
+static void
+run (void *cls,
+     char *const *args,
+     const char *cfgfile,
+     const struct GNUNET_CONFIGURATION_Handle *c)
+{
+  (void) cls;
+  (void) args;
+  (void) cfgfile;
+  cfg = c;
+  if (NULL ==
+      (db_plugin = ANASTASIS_DB_plugin_load (cfg)))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to initialize DB subsystem\n");
+    global_ret = EXIT_NOTCONFIGURED;
+    return;
+  }
+  // FIXME: initialize 'auth' from cfg!
+
+  GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
+                                 cls);
+  ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule,
+                          &rc);
+  rc = GNUNET_CURL_gnunet_rc_create (ctx);
+  if (NULL == ctx)
+  {
+    GNUNET_break (0);
+    return;
+  }
+  latest_row_off = FIXME; // need new DB function!
+
+  task = GNUNET_SCHEDULER_add_now (&find_transfers,
+                                   NULL);
+}
+
+
+/**
+ * The main function of anastasis-helper-authorization-iban
+ *
+ * @param argc number of arguments from the command line
+ * @param argv command line arguments
+ * @return 0 ok, non-zero on error
+ */
+int
+main (int argc,
+      char *const *argv)
+{
+  struct GNUNET_GETOPT_CommandLineOption options[] = {
+    GNUNET_GETOPT_option_flag ('t',
+                               "test",
+                               "run in test mode and exit when idle",
+                               &test_mode),
+    GNUNET_GETOPT_OPTION_END
+  };
+  enum GNUNET_GenericReturnValue ret;
+
+  if (GNUNET_OK !=
+      GNUNET_STRINGS_get_utf8_args (argc, argv,
+                                    &argc, &argv))
+    return EXIT_INVALIDARGUMENT;
+  ANASTASIS_OS_init ();
+  ret = GNUNET_PROGRAM_run (
+    argc, argv,
+    "anastasis-helper-authorization-iban",
+    gettext_noop (
+      "background process that watches for incoming wire transfers from 
customers"),
+    options,
+    &run, NULL);
+  GNUNET_free_nz ((void *) argv);
+  if (GNUNET_SYSERR == ret)
+    return EXIT_INVALIDARGUMENT;
+  if (GNUNET_NO == ret)
+    return EXIT_SUCCESS;
+  return global_ret;
+}
+
+
+/* end of anastasis-helper-authorization-iban.c */
diff --git a/src/include/anastasis_service.h b/src/include/anastasis_service.h
index a08f25b..bec89d1 100644
--- a/src/include/anastasis_service.h
+++ b/src/include/anastasis_service.h
@@ -475,7 +475,13 @@ enum ANASTASIS_KeyShareDownloadStatus
    * authentication check until the request timeout
    * was reached. The client should try again later.
    */
-  ANASTASIS_KSD_AUTHENTICATION_TIMEOUT
+  ANASTASIS_KSD_AUTHENTICATION_TIMEOUT,
+
+  /**
+   * The plugin provided external challenge instructions
+   * that should be followed. They are method-specific.
+   */
+  ANASTASIS_KSD_EXTERNAL_CHALLENGE_INSTRUCTIONS
 
 };
 
@@ -584,6 +590,12 @@ struct ANASTASIS_KeyShareDownloadDetails
 
     } server_failure;
 
+    /**
+     * External challenge instructions, if @e status is
+     * #ANASTASIS_KSD_EXTERNAL_CHALLENGE_INSTRUCTIONS.
+     */
+    const json_t *external_challenge;
+
   } details;
 };
 
diff --git a/src/restclient/anastasis_api_keyshare_lookup.c 
b/src/restclient/anastasis_api_keyshare_lookup.c
index 6df00dd..bb463b6 100644
--- a/src/restclient/anastasis_api_keyshare_lookup.c
+++ b/src/restclient/anastasis_api_keyshare_lookup.c
@@ -150,16 +150,30 @@ handle_keyshare_lookup_finished (void *cls,
     {
       GNUNET_break_op (0);
       kdd.status = ANASTASIS_KSD_SERVER_ERROR;
+      kdd.details.server_failure.http_status = MHD_HTTP_ACCEPTED;
+      kdd.details.server_failure.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
       break;
     }
     /* Success, call callback with all details! */
     memcpy (&kdd.details.eks,
             data,
             data_size);
-    kslo->cb (kslo->cb_cls,
-              &kdd);
-    ANASTASIS_keyshare_lookup_cancel (kslo);
-    return;
+    break;
+  case MHD_HTTP_ACCEPTED:
+    kdd.details.external_challenge = json_loadb (data,
+                                                 data_size,
+                                                 JSON_REJECT_DUPLICATES,
+                                                 NULL);
+    if (NULL == kdd.details.external_challenge)
+    {
+      GNUNET_break_op (0);
+      kdd.status = ANASTASIS_KSD_SERVER_ERROR;
+      kdd.details.server_failure.http_status = MHD_HTTP_ACCEPTED;
+      kdd.details.server_failure.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
+      break;
+    }
+    kdd.status = ANASTASIS_KSD_EXTERNAL_CHALLENGE_INSTRUCTIONS;
+    break;
   case MHD_HTTP_BAD_REQUEST:
     /* This should never happen, either us or the anastasis server is buggy
        (or API version conflict); just pass JSON reply to the application */
@@ -206,24 +220,16 @@ handle_keyshare_lookup_finished (void *cls,
     /* Nothing really to verify, authentication required/failed */
     kdd.status = ANASTASIS_KSD_REDIRECT_FOR_AUTHENTICATION;
     kdd.details.redirect_url = kslo->location;
-    kslo->cb (kslo->cb_cls,
-              &kdd);
-    ANASTASIS_keyshare_lookup_cancel (kslo);
-    return;
+    break;
   case MHD_HTTP_ALREADY_REPORTED:
   case MHD_HTTP_FORBIDDEN:
     /* Nothing really to verify, authentication required/failed */
-    {
-      kdd.status = ANASTASIS_KSD_INVALID_ANSWER;
-      kdd.details.open_challenge.body = data;
-      kdd.details.open_challenge.body_size = data_size;
-      kdd.details.open_challenge.content_type = kslo->content_type;
-      kdd.details.open_challenge.http_status = response_code;
-      kslo->cb (kslo->cb_cls,
-                &kdd);
-    }
-    ANASTASIS_keyshare_lookup_cancel (kslo);
-    return;
+    kdd.status = ANASTASIS_KSD_INVALID_ANSWER;
+    kdd.details.open_challenge.body = data;
+    kdd.details.open_challenge.body_size = data_size;
+    kdd.details.open_challenge.content_type = kslo->content_type;
+    kdd.details.open_challenge.http_status = response_code;
+    break;
   case MHD_HTTP_NOT_FOUND:
     /* Nothing really to verify */
     kdd.status = ANASTASIS_KSD_TRUTH_UNKNOWN;

-- 
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]