gnunet-svn
[Top][All Lists]
Advanced

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

[taler-anastasis] branch master updated: redux WIP, FTBFS


From: gnunet
Subject: [taler-anastasis] branch master updated: redux WIP, FTBFS
Date: Mon, 15 Feb 2021 22:13:36 +0100

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 24e9072  redux WIP, FTBFS
24e9072 is described below

commit 24e907211bfc2cb2550d57800dde5df1837bec6d
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Mon Feb 15 22:13:34 2021 +0100

    redux WIP, FTBFS
---
 src/reducer/anastasis_api_recovery_redux.c | 320 ++++++++++++++++
 src/reducer/anastasis_api_redux.c          | 567 ++++++++++-------------------
 src/reducer/anastasis_api_redux.h          |  87 +----
 3 files changed, 536 insertions(+), 438 deletions(-)

diff --git a/src/reducer/anastasis_api_recovery_redux.c 
b/src/reducer/anastasis_api_recovery_redux.c
index b795568..a1432e1 100644
--- a/src/reducer/anastasis_api_recovery_redux.c
+++ b/src/reducer/anastasis_api_recovery_redux.c
@@ -501,6 +501,73 @@ check_policy_fulfilled (json_t *state)
 }
 
 
+/**
+ * State for a "recover secret" CMD.
+ */
+struct RecoverSecretState
+{
+  /**
+   * URL of the anastasis backend.
+   */
+  const char *anastasis_url;
+
+  /**
+   * The /policy GET operation handle.
+   */
+  struct ANASTASIS_Recovery *recovery;
+
+  /**
+   * Identification data from the user
+   */
+  json_t *id_data;
+
+  /**
+   * Salt to be used to derive the id
+   */
+  struct ANASTASIS_CRYPTO_PowSalt *salt;
+
+  /**
+   * Recovery information from the lookup
+   */
+  struct ANASTASIS_RecoveryInformation *ri;
+
+  /**
+   * Information about the challenges.
+   */
+  struct ANASTASIS_Challenge **challenges;
+
+  /**
+   * Reference to a state.
+   */
+  json_t *state;
+
+  /**
+   * callback (#DispatchHandler) to call during/after operation
+   */
+  ANASTASIS_ActionCallback cb;
+
+  /**
+   * closure fpr action callback
+   */
+  void *cb_cls;
+
+  /**
+   * Expected status code.
+   */
+  unsigned int http_status;
+
+  /**
+   * version of the recovery document
+   */
+  unsigned int version;
+
+  /**
+   * Amount of challenges.
+   */
+  unsigned int challenges_length;
+};
+
+
 // static
 void
 challenge_answer_cb (void *af_cls,
@@ -703,3 +770,256 @@ ANASTASIS_recovery_action_ (json_t *state,
                          action);
   return NULL;
 }
+
+
+static void
+policy_lookup_cb (void *cls,
+                  const struct ANASTASIS_RecoveryInformation *ri)
+{
+  struct RecoverSecretState *rss = cls;
+  json_t *policies;
+  json_t *challenges;
+  json_t *recovery_information;
+
+  recovery_information = json_object_get (rss->state,
+                                          "recovery_information");
+  if (NULL == recovery_information)
+  {
+    recovery_information = json_object ();
+    GNUNET_assert (json_is_object (recovery_information));
+    policies = json_array ();
+    GNUNET_assert (json_is_array (policies));
+    challenges = json_array ();
+    GNUNET_assert (json_is_array (challenges));
+  }
+  else
+  {
+    GNUNET_assert (
+      json_is_array (
+        json_object_get (recovery_information,
+                         "policies")));
+    GNUNET_assert (
+      json_is_array (
+        json_object_get (recovery_information,
+                         "challenges")));
+    return;
+  }
+
+  if (NULL == ri)
+  {
+    GNUNET_break (0);
+    return;
+  }
+  rss->ri = (struct ANASTASIS_RecoveryInformation *) ri;
+  rss->http_status = MHD_HTTP_OK;
+
+  for (unsigned int i = 0; i < rss->ri->cs_len; i++)
+  {
+    struct ANASTASIS_Challenge *ci = rss->ri->cs[i];
+    bool contains = false;
+
+    for (unsigned int i = 0; i < rss->challenges_length; i++)
+    {
+      if (rss->challenges[i] == rss->ri->cs[i])
+      {
+        contains = true;
+        break;
+      }
+    }
+    if (! contains)
+    {
+      GNUNET_array_append (rss->challenges,
+                           rss->challenges_length,
+                           ci);
+#if FIXME
+      /* should probably only serialize the uuid and
+         what the UI needs! */
+      GNUNET_assert (
+        0 == json_array_append_new (
+          challenges,
+          ANASTASIS_challenge_information_to_json (ci)));
+#endif
+    }
+  }
+  for (unsigned int i = 0; i < ri->dps_len; i++)
+  {
+    json_t *policy = json_array ();
+
+    GNUNET_assert (json_is_array (policy));
+    for (unsigned int j = 0; j < ri->dps[i]->challenges_length; j++)
+    {
+      for (unsigned int k = 0; k < rss->challenges_length; k++)
+      {
+        if (ri->dps[i]->challenges[j] == rss->challenges[k])
+          GNUNET_assert (
+            0 == json_array_append_new (policy,
+                                        json_integer ((json_int_t) k)));
+      }
+    }
+    if (0 < json_array_size (policy))
+      GNUNET_assert (
+        0 == json_array_append_new (policies,
+                                    policy));
+  }
+  if ((0 < json_array_size (challenges))
+      && (0 < json_array_size (policies)))
+  {
+    GNUNET_assert (
+      0 == json_object_set_new (recovery_information,
+                                "provider_url",
+                                json_string (rss->anastasis_url)));
+    GNUNET_assert (
+      0 == json_object_set_new (recovery_information,
+                                "version",
+                                json_integer (rss->version)));
+    GNUNET_assert (
+      0 == json_object_set_new (recovery_information,
+                                "policies",
+                                policies));
+    GNUNET_assert (
+      0 == json_object_set_new (recovery_information,
+                                "challenges",
+                                challenges));
+    GNUNET_assert (
+      0 == json_object_set_new (rss->state,
+                                "recovery_information",
+                                recovery_information));
+    rss->cb (NULL,
+             TALER_EC_NONE,
+             rss->state);
+    // rss->cb = NULL;
+  }
+  else
+  {
+    json_decref (challenges);
+    json_decref (policies);
+    json_decref (recovery_information);
+    ANASTASIS_redux_fail_ (rss->cb,
+                           rss->cb_cls,
+                           TALER_EC_ANASTASIS_REDUCER_ACTION_INVALID, // 
FIXME: Error code
+                           "Failed fetching recovery information!");
+  }
+  rss->recovery = NULL;
+}
+
+
+/**
+ * Function to free a #RecoverSecretState.
+ *
+ * @param cls closure for a #RecoverSecretState.
+ */
+static void
+free_enter_user_attributes (void *cls)
+{
+  struct RecoverSecretState *rss = cls;
+
+  if (NULL != rss->recovery)
+  {
+    /* must run first, or at least before #core_secret_cb */
+    (void) GNUNET_SCHEDULER_add_with_priority (
+      GNUNET_SCHEDULER_PRIORITY_SHUTDOWN,
+      &delayed_abort,
+      rss->recovery);
+    rss->recovery = NULL;
+  }
+  GNUNET_free (rss->challenges);
+  json_decref (rss->state);
+  json_decref (rss->id_data);
+  GNUNET_free (rss);
+}
+
+
+struct ANASTASIS_ReduxAction *
+ANASTASIS_REDUX_backup_challenge_begin_ (json_t *state,
+                                         const json_t *arguments,
+                                         ANASTASIS_ActionCallback cb,
+                                         void *cb_cls)
+{
+  json_t *version;
+  json_t *providers;
+  json_t *p_value;
+  const char *p_key;
+  struct RecoverSecretState *rss
+    = GNUNET_new (struct RecoverSecretState);
+
+  providers = json_object_get (state,
+                               "authentication_providers");
+  GNUNET_assert (NULL != providers);
+  rss->id_data = attributes;
+  version = json_object_get (arguments,
+                             "version");
+  if (NULL != version)
+    rss->version = (unsigned int) json_integer_value (version);
+  rss->challenges_length = 0;
+  redux_transition (state,
+                    ANASTASIS_RECOVERY_STATE_CHALLENGE_SELECTING);
+  rss->state = json_incref (state);
+  rss->cb = cb;
+  rss->cb_cls = cb_cls;
+
+  json_object_foreach (providers, p_key, p_value)
+  {
+    json_t *m_value;
+    size_t m_index;
+
+    GNUNET_assert (json_is_array (p_value));
+    json_array_foreach (p_value, m_index, m_value)
+    {
+      struct ANASTASIS_CRYPTO_PowSalt salt;
+      json_t *provider_data;
+      json_t *provider_url;
+      const char *salt_str;
+      void *iter = json_object_iter (m_value);
+      const char *key = json_object_iter_key (iter);
+
+      provider_data = json_object_get (m_value,
+                                       key);
+      GNUNET_assert (NULL != provider_data);
+      provider_url = json_object_get (provider_data,
+                                      "provider_url");
+      rss->anastasis_url = json_string_value (provider_url);
+      GNUNET_assert (NULL != provider_url);
+      salt_str = json_string_value (
+        json_object_get (provider_data,
+                         "provider_salt"));
+      GNUNET_assert (NULL != salt_str);
+      GNUNET_assert (
+        GNUNET_OK ==
+        GNUNET_STRINGS_string_to_data (salt_str,
+                                       strlen (salt_str),
+                                       &salt,
+                                       sizeof (struct
+                                               ANASTASIS_CRYPTO_PowSalt)));
+      rss->recovery =
+        ANASTASIS_recovery_begin (
+          ANASTASIS_REDUX_ctx_,
+          rss->id_data,
+          (NULL != version)
+            ? rss->version
+            : 0,
+          rss->anastasis_url,
+          &salt,
+          &policy_lookup_cb,
+          rss,
+          NULL,
+          NULL);
+
+      if (NULL == rss->recovery)
+      {
+        GNUNET_break (0);
+        cb (cb_cls,
+            TALER_EC_NONE,
+            state);
+        return NULL;
+      }
+    }
+  }
+  {
+    struct ANASTASIS_ReduxAction *ra;
+
+    ra = GNUNET_new (struct ANASTASIS_ReduxAction);
+    ra->cleanup_cls = rss;
+    ra->cleanup = free_enter_user_attributes;
+    return ra;
+  }
+}
diff --git a/src/reducer/anastasis_api_redux.c 
b/src/reducer/anastasis_api_redux.c
index 85787d2..649e3f9 100644
--- a/src/reducer/anastasis_api_redux.c
+++ b/src/reducer/anastasis_api_redux.c
@@ -129,6 +129,29 @@ redux_transition (json_t *state,
 }
 
 
+/**
+ * #ANASTASIS_REDUX_add_provider_to_state_ waiting for the
+ * configuration request to complete or fail.
+ */
+struct ConfigReduxWaiting
+{
+  /**
+   * Kept in a DLL.
+   */
+  struct ConfigReduxWaiting *prev;
+
+  /**
+   * Kept in a DLL.
+   */
+  struct ConfigReduxWaiting *next;
+
+  /**
+   * Associated redux action.
+   */
+  struct ANASTASIS_ReduxAction *ra;
+};
+
+
 /**
  * State for a "get config" operation.
  */
@@ -145,6 +168,16 @@ struct ConfigRequest
    */
   struct ConfigRequest *prev;
 
+  /**
+   * Head of DLL of REDUX operations waiting for an answer.
+   */
+  struct ConfigReduxWaiting *w_head;
+
+  /**
+   * Tail of DLL of REDUX operations waiting for an answer.
+   */
+  struct ConfigReduxWaiting *w_tail;
+
   /**
    * Obtained status code.
    */
@@ -774,9 +807,24 @@ select_country (json_t *state,
                            "'currency' missing");
     return NULL;
   }
+  {
+    enum TALER_ErrorCode ec;
+
+    ec = begin_provider_config_check (currency);
+    if (TALER_EC_NONE != ec)
+    {
+      GNUNET_break (0);
+      ANASTASIS_redux_fail_ (cb,
+                             cb_cls,
+                             ec,
+                             currency);
+      return NULL;
+    }
+  }
   redux_id_attr = redux_id_attr_init (json_string_value (country));
   if (NULL == redux_id_attr)
   {
+    GNUNET_break (0);
     ANASTASIS_redux_fail_ (cb,
                            cb_cls,
                            TALER_EC_ANASTASIS_REDUCER_RESOURCE_MISSING,
@@ -807,7 +855,6 @@ select_country (json_t *state,
                  json_object_set (state,
                                   "required_attributes",
                                   (json_t *) required_attrs));
-  begin_provider_config_check (currency);
   return NULL;
 }
 
@@ -865,22 +912,53 @@ unselect_continent (json_t *state,
 
 
 #if 0
+
+static void
+config_finished (struct ConfigReduxWaiting *w,
+                 struct ConfigRequest *cr)
+{
+  struct ANASTASIS_ReduxAction *ra = w->ra;
+  GNUNET_CONTAINER_DLL_remove (cr->w_head,
+                               cr->w_tail,
+                               w);
+  GNUNET_free (w);
+}
+
+
 /**
- * Adds the server configuration from async #ConfigRequest
- * to the json state.
+ * Adds the server configuration of the Anastasis provider
+ * at @a url to the json @a state.  Checks if we have
+ * the provider information already available. If so,
+ * imports it into @a state. If not, queries the provider,
+ * generating a success or failure outcome asynchronously.
  *
  * @param cr the config request
- * @param state the json state to operate on
+ * @param[in,out] state the json state to operate on
+ * @param cb callback to call during/after operation
+ * @param cb_cls callback closure
+ * @return handle to cancel asynchronous operation, NULL if
+ *         we completed synchronously
  */
-static void
-add_config_to_state (struct ConfigRequest *cr,
-                     json_t *state)
+struct ANASTASIS_ReduxAction *
+ANASTASIS_REDUX_add_provider_to_state_ (const char *url,
+                                        json_t *state,
+                                        ANASTASIS_ActionCallback cb,
+                                        void *cb_cls)
 {
+  struct ConfigRequest *cr = FIXME;
+  struct ConfigReduxWaiting *w;
   json_t *method;
   size_t index;
   json_t *provider_list;
-  json_t *methods_list = json_object_get (cr->backend_methods,
-                                          "methods");
+  json_t *methods_list;
+
+  w = GNUNET_new (struct ConfigReduxWaiting);
+  GNUNET_CONTAINER_DLL_insert (cr->w_head,
+                               cr->w_tail,
+                               w);
+
+  methods_list = json_object_get (cr->backend_methods,
+                                  "methods");
 
   if (NULL == (provider_list = json_object_get (state,
                                                 "authentication_providers")))
@@ -899,7 +977,7 @@ add_config_to_state (struct ConfigRequest *cr,
                                                                   "method"));
     json_t *ma_arr;
     json_t *prov;
-    json_t *ma = json_object ();
+    json_t *ma = json_object (); // FIXME: odd structure!
 
     if (NULL == (ma_arr = json_object_get (provider_list,
                                            method_type)))
@@ -909,11 +987,7 @@ add_config_to_state (struct ConfigRequest *cr,
                                           method_type,
                                           ma_arr = json_array ()));
     }
-    char *provider_salt = GNUNET_STRINGS_data_to_string_alloc (
-      &cr->backend_salt,
-      sizeof (struct
-              ANASTASIS_CRYPTO_PowSalt));
-    prov = json_pack ("{s:o, s:o, s:o, s:s, s:s, s:s}",
+    prov = json_pack ("{s:o, s:o, s:o, s:s, s:s, s:o}",
                       "method_cost",
                       json_object_get (method,
                                        "cost"),
@@ -926,185 +1000,21 @@ add_config_to_state (struct ConfigRequest *cr,
                       "provider_name",
                       cr->backend_name,
                       "provider_salt",
-                      provider_salt);
-    GNUNET_free (provider_salt);
-    GNUNET_assert (0 == json_object_set_new (ma,
-                                             cr->backend_id,
-                                             prov));
-    GNUNET_assert (0 == json_array_append_new (ma_arr, ma));
-  }
-}
-
-
-/**
- * Function which collects all configurations from the different
- * servers and calls the #ANASTASIS_ActionCallback.
- *
- * @param sch a handle to a country selection action
- */
-static void
-conclude_select_country (struct SelectCountryHandle *sch)
-{
-  struct ConfigRequest *cr;
-  const char *currency;
-
-  currency = json_string_value (json_object_get (sch->state,
-                                                 "currency"));
-  while (NULL != (cr = sch->cr_head))
-  {
-    GNUNET_CONTAINER_DLL_remove (sch->cr_head,
-                                 sch->cr_tail,
-                                 cr);
-    if ( (MHD_HTTP_OK != cr->http_status) ||
-         (0 != strcmp (cr->backend_currency,
-                       currency)) )
-    {
-      free_config_request (cr);
-      continue;
-    }
-    add_config_to_state (cr,
-                         sch->state);
+                      GNUNET_JSON_from_data_auto (&cr->provider_salt));
+    GNUNET_assert (0 ==
+                   json_object_set_new (ma,
+                                        cr->backend_id,
+                                        prov));
+    GNUNET_assert (0 ==
+                   json_array_append_new (ma_arr,
+                                          ma));
   }
-  sch->cb (NULL,
-           TALER_EC_NONE,
-           sch->state);
 }
 
 
 #endif
 
 
-static void
-policy_lookup_cb (void *cls,
-                  const struct ANASTASIS_RecoveryInformation *ri)
-{
-  struct RecoverSecretState *rss = cls;
-  json_t *policies;
-  json_t *challenges;
-  json_t *recovery_information;
-
-  recovery_information = json_object_get (rss->state,
-                                          "recovery_information");
-  if (NULL == recovery_information)
-  {
-    recovery_information = json_object ();
-    GNUNET_assert (json_is_object (recovery_information));
-    policies = json_array ();
-    GNUNET_assert (json_is_array (policies));
-    challenges = json_array ();
-    GNUNET_assert (json_is_array (challenges));
-  }
-  else
-  {
-    GNUNET_assert (
-      json_is_array (
-        json_object_get (recovery_information,
-                         "policies")));
-    GNUNET_assert (
-      json_is_array (
-        json_object_get (recovery_information,
-                         "challenges")));
-    return;
-  }
-
-  if (NULL == ri)
-  {
-    GNUNET_break (0);
-    return;
-  }
-  rss->ri = (struct ANASTASIS_RecoveryInformation *) ri;
-  rss->http_status = MHD_HTTP_OK;
-
-  for (unsigned int i = 0; i < rss->ri->cs_len; i++)
-  {
-    struct ANASTASIS_Challenge *ci = rss->ri->cs[i];
-    bool contains = false;
-
-    for (unsigned int i = 0; i < rss->challenges_length; i++)
-    {
-      if (rss->challenges[i] == rss->ri->cs[i])
-      {
-        contains = true;
-        break;
-      }
-    }
-    if (! contains)
-    {
-      GNUNET_array_append (rss->challenges,
-                           rss->challenges_length,
-                           ci);
-#if FIXME
-      /* should probably only serialize the uuid and
-         what the UI needs! */
-      GNUNET_assert (
-        0 == json_array_append_new (
-          challenges,
-          ANASTASIS_challenge_information_to_json (ci)));
-#endif
-    }
-  }
-  for (unsigned int i = 0; i < ri->dps_len; i++)
-  {
-    json_t *policy = json_array ();
-
-    GNUNET_assert (json_is_array (policy));
-    for (unsigned int j = 0; j < ri->dps[i]->challenges_length; j++)
-    {
-      for (unsigned int k = 0; k < rss->challenges_length; k++)
-      {
-        if (ri->dps[i]->challenges[j] == rss->challenges[k])
-          GNUNET_assert (
-            0 == json_array_append_new (policy,
-                                        json_integer ((json_int_t) k)));
-      }
-    }
-    if (0 < json_array_size (policy))
-      GNUNET_assert (
-        0 == json_array_append_new (policies,
-                                    policy));
-  }
-  if ((0 < json_array_size (challenges))
-      && (0 < json_array_size (policies)))
-  {
-    GNUNET_assert (
-      0 == json_object_set_new (recovery_information,
-                                "provider_url",
-                                json_string (rss->anastasis_url)));
-    GNUNET_assert (
-      0 == json_object_set_new (recovery_information,
-                                "version",
-                                json_integer (rss->version)));
-    GNUNET_assert (
-      0 == json_object_set_new (recovery_information,
-                                "policies",
-                                policies));
-    GNUNET_assert (
-      0 == json_object_set_new (recovery_information,
-                                "challenges",
-                                challenges));
-    GNUNET_assert (
-      0 == json_object_set_new (rss->state,
-                                "recovery_information",
-                                recovery_information));
-    rss->cb (NULL,
-             TALER_EC_NONE,
-             rss->state);
-    // rss->cb = NULL;
-  }
-  else
-  {
-    json_decref (challenges);
-    json_decref (policies);
-    json_decref (recovery_information);
-    ANASTASIS_redux_fail_ (rss->cb,
-                           rss->cb_cls,
-                           TALER_EC_ANASTASIS_REDUCER_ACTION_INVALID, // 
FIXME: Error code
-                           "Failed fetching recovery information!");
-  }
-  rss->recovery = NULL;
-}
-
-
 static void
 delayed_abort (void *cls)
 {
@@ -1114,32 +1024,6 @@ delayed_abort (void *cls)
 }
 
 
-/**
- * Function to free a #RecoverSecretState.
- *
- * @param cls closure for a #RecoverSecretState.
- */
-static void
-free_enter_user_attributes (void *cls)
-{
-  struct RecoverSecretState *rss = cls;
-
-  if (NULL != rss->recovery)
-  {
-    /* must run first, or at least before #core_secret_cb */
-    (void) GNUNET_SCHEDULER_add_with_priority (
-      GNUNET_SCHEDULER_PRIORITY_SHUTDOWN,
-      &delayed_abort,
-      rss->recovery);
-    rss->recovery = NULL;
-  }
-  GNUNET_free (rss->challenges);
-  json_decref (rss->state);
-  json_decref (rss->id_data);
-  GNUNET_free (rss);
-}
-
-
 /**
  * DispatchHandler/Callback function which is called for a
  * "enter_user_attributes" action.
@@ -1157,190 +1041,131 @@ enter_user_attributes (json_t *state,
                        ANASTASIS_ActionCallback cb,
                        void *cb_cls)
 {
-  size_t index;
-  json_t *attributes;
-  json_t *required_attribute;
-  json_t *required_attributes;
+  const json_t *attributes;
+  const json_t *required_attributes;
 
-  GNUNET_assert (NULL != state);
   if (NULL == arguments)
   {
     ANASTASIS_redux_fail_ (cb,
                            cb_cls,
-                           TALER_EC_ANASTASIS_REDUCER_ACTION_INVALID,
-                           "enter_user_attributes");
+                           TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
+                           "arguments missing");
     return NULL;
   }
   attributes = json_object_get (arguments,
                                 "identity_attributes");
-  GNUNET_assert (NULL != attributes);
-  json_object_set (state,
-                   "identity_attributes",
-                   attributes);
-
-  required_attributes = json_object_get (state,
-                                         "required_attributes");
-  GNUNET_assert (json_is_array (required_attributes));
-  json_array_foreach (required_attributes, index, required_attribute)
+  if (NULL == attributes)
   {
-    const char *name;
-    const char *attribute_value;
-    const char *regexp;
-    const char *reglog;
-    bool (*regfun)(const char *);
-
-    name = json_string_value (json_object_get (required_attribute,
-                                               "name"));
-    attribute_value = json_string_value (json_object_get (attributes,
-                                                          name));
-    regexp = json_string_value (json_object_get (required_attribute,
-                                                 "validation-regex"));
-    if ( (NULL != regexp) &&
-         (! validate_regex (attribute_value,
-                            regexp)) )
-    {
-      json_t *error = json_pack (
-        "{s:I, s:s}",
-        "code",
-        (json_int_t)
-        TALER_EC_ANASTASIS_REDUCER_INPUT_REGEX_FAILED,
-        "hint", regexp);
-      cb (cb_cls,
-          TALER_EC_INVALID,
-          error);
-      json_decref (attributes);
-      json_decref (error);
-      return NULL;
-    }
-    reglog = json_string_value (json_object_get (required_attribute,
-                                                 "validation-logic"));
-    if ( (NULL != reglog) &&
-         (NULL != (regfun = dlsym (RTLD_DEFAULT,
-                                   reglog))) &&
-         (! regfun (attribute_value)) )
-    {
-      json_t *error = json_pack (
-        "{s:I, s:s}",
-        "code",
-        (json_int_t)
-        TALER_EC_ANASTASIS_REDUCER_INPUT_VALIDATION_FAILED,
-        "hint", reglog);
-      cb (cb_cls,
-          TALER_EC_INVALID,
-          error);
-      json_decref (attributes);
-      json_decref (error);
-      return NULL;
-    }
+    ANASTASIS_redux_fail_ (cb,
+                           cb_cls,
+                           TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
+                           "'identity_attributes' missing");
+    return NULL;
   }
+  GNUNET_assert (0 ==
+                 json_object_set (state,
+                                  "identity_attributes",
+                                  (json_t *) attributes));
 
-  const char *s_mode = get_state_mode (state);
-  GNUNET_assert (NULL != s_mode);
-  json_t *auth_providers = json_object_get (arguments,
-                                            "authentication_providers");
-
-  if (0 == strcmp (s_mode, "backup_state"))
+  /* Verify required attributes are present and well-formed */
+  required_attributes = json_object_get (state,
+                                         "required_attributes");
+  if ( (NULL == required_attributes) ||
+       (! json_is_array (required_attributes)) )
   {
-    redux_transition (state,
-                      ANASTASIS_BACKUP_STATE_AUTHENTICATIONS_EDITING);
-    if (NULL != auth_providers)
-      json_object_set_new (state,
-                           "authentication_providers",
-                           auth_providers);
-    cb (cb_cls,
-        TALER_EC_NONE,
-        state);
-    json_decref (attributes);
+    ANASTASIS_redux_fail_ (cb,
+                           cb_cls,
+                           TALER_EC_ANASTASIS_REDUCER_STATE_INVALID,
+                           "'required_attributes' must be an array");
     return NULL;
   }
-  else
   {
-    json_t *version;
-    json_t *providers;
-    json_t *p_value;
-    const char *p_key;
-    struct RecoverSecretState *rss
-      = GNUNET_new (struct RecoverSecretState);
-
-    providers = json_object_get (state,
-                                 "authentication_providers");
-    GNUNET_assert (NULL != providers);
-    rss->id_data = attributes;
-    version = json_object_get (arguments,
-                               "version");
-    if (NULL != version)
-      rss->version = (unsigned int) json_integer_value (version);
-    rss->challenges_length = 0;
-    redux_transition (state,
-                      ANASTASIS_RECOVERY_STATE_CHALLENGE_SELECTING);
-    rss->state = json_incref (state);
-    rss->cb = cb;
-    rss->cb_cls = cb_cls;
+    size_t index;
+    json_t *required_attribute;
 
-    json_object_foreach (providers, p_key, p_value)
+    json_array_foreach (required_attributes, index, required_attribute)
     {
-      json_t *m_value;
-      size_t m_index;
+      const char *name;
+      const char *attribute_value;
+      const char *regexp = NULL;
+      const char *reglog = NULL;
+      struct GNUNET_JSON_Specification spec[] = {
+        GNUNET_JSON_spec_string ("name",
+                                 &name),
+        GNUNET_JSON_spec_mark_optional (
+          GNUNET_JSON_spec_string ("validation-regex",
+                                   &regexp)),
+        GNUNET_JSON_spec_mark_optional (
+          GNUNET_JSON_spec_string ("validation-logic",
+                                   &reglog)),
+        GNUNET_JSON_spec_end ()
+      };
+
+      if (GNUNET_OK !=
+          GNUNET_JSON_parse (required_attribute,
+                             spec,
+                             NULL, NULL))
+      {
+        GNUNET_break (0);
+        ANASTASIS_redux_fail_ (cb,
+                               cb_cls,
+                               TALER_EC_ANASTASIS_REDUCER_STATE_INVALID,
+                               "'required_attributes' lacks required fields");
+        return NULL;
+      }
+
+      attribute_value = json_string_value (json_object_get (attributes,
+                                                            name));
+      if ( (NULL != regexp) &&
+           (! validate_regex (attribute_value,
+                              regexp)) )
+      {
+        ANASTASIS_redux_fail (cb,
+                              cb_cls,
+                              TALER_EC_ANASTASIS_REDUCER_INPUT_REGEX_FAILED,
+                              regexp);
+        return NULL;
+      }
 
-      GNUNET_assert (json_is_array (p_value));
-      json_array_foreach (p_value, m_index, m_value)
+      if (NULL != reglog)
       {
-        struct ANASTASIS_CRYPTO_PowSalt salt;
-        json_t *provider_data;
-        json_t *provider_url;
-        const char *salt_str;
-        void *iter = json_object_iter (m_value);
-        const char *key = json_object_iter_key (iter);
-
-        provider_data = json_object_get (m_value,
-                                         key);
-        GNUNET_assert (NULL != provider_data);
-        provider_url = json_object_get (provider_data,
-                                        "provider_url");
-        rss->anastasis_url = json_string_value (provider_url);
-        GNUNET_assert (NULL != provider_url);
-        salt_str = json_string_value (
-          json_object_get (provider_data,
-                           "provider_salt"));
-        GNUNET_assert (NULL != salt_str);
-        GNUNET_assert (
-          GNUNET_OK ==
-          GNUNET_STRINGS_string_to_data (salt_str,
-                                         strlen (salt_str),
-                                         &salt,
-                                         sizeof (struct
-                                                 ANASTASIS_CRYPTO_PowSalt)));
-        rss->recovery =
-          ANASTASIS_recovery_begin (
-            ANASTASIS_REDUX_ctx_,
-            rss->id_data,
-            (NULL != version)
-            ? rss->version
-            : 0,
-            rss->anastasis_url,
-            &salt,
-            &policy_lookup_cb,
-            rss,
-            NULL,
-            NULL);
-
-        if (NULL == rss->recovery)
+        bool (*regfun)(const char *);
+
+        if ( (NULL != (regfun = dlsym (RTLD_DEFAULT,
+                                       reglog))) &&
+             (! regfun (attribute_value)) )
         {
-          GNUNET_break (0);
-          cb (cb_cls,
-              TALER_EC_NONE,
-              state);
+          ANASTASIS_redux_fail (cb,
+                                cb_cls,
+                                
TALER_EC_ANASTASIS_REDUCER_INPUT_VALIDATION_FAILED,
+                                reglog);
           return NULL;
         }
       }
+    } /* end for all attributes loop */
+  } /* end for all attributes scope */
+
+  /* Transition based on mode */
+  {
+    const char *s_mode = get_state_mode (state);
+
+    if (0 == strcmp (s_mode,
+                     "backup_state"))
+    {
+      redux_transition (state,
+                        ANASTASIS_BACKUP_STATE_AUTHENTICATIONS_EDITING);
+      cb (cb_cls,
+          TALER_EC_NONE,
+          state);
+      return NULL;
     }
+    else
     {
-      struct ANASTASIS_ReduxAction *ra;
-
-      ra = GNUNET_new (struct ANASTASIS_ReduxAction);
-      ra->cleanup_cls = rss;
-      ra->cleanup = free_enter_user_attributes;
-      return ra;
+      redux_transition (state,
+                        ANASTASIS_BACKUP_STATE_CHALLENGE_SELECTING);
+      return backup_challenge_begin (state,
+                                     cb,
+                                     cb_cls);
     }
   }
 }
diff --git a/src/reducer/anastasis_api_redux.h 
b/src/reducer/anastasis_api_redux.h
index e1f04f4..63f72b2 100644
--- a/src/reducer/anastasis_api_redux.h
+++ b/src/reducer/anastasis_api_redux.h
@@ -149,73 +149,6 @@ ANASTASIS_redux_fail_ (ANASTASIS_ActionCallback cb,
                        const char *detail);
 
 
-/**
- * State for a "recover secret" CMD.
- */
-struct RecoverSecretState
-{
-  /**
-   * URL of the anastasis backend.
-   */
-  const char *anastasis_url;
-
-  /**
-   * Expected status code.
-   */
-  unsigned int http_status;
-
-  /**
-   * The /policy GET operation handle.
-   */
-  struct ANASTASIS_Recovery *recovery;
-
-  /**
-   * Identification data from the user
-   */
-  json_t *id_data;
-
-  /**
-   * version of the recovery document
-   */
-  unsigned int version;
-
-  /**
-   * Salt to be used to derive the id
-   */
-  struct ANASTASIS_CRYPTO_PowSalt *salt;
-
-  /**
-   * Recovery information from the lookup
-   */
-  struct ANASTASIS_RecoveryInformation *ri;
-
-  /**
-   * Information about the challenges.
-   */
-  struct ANASTASIS_Challenge **challenges;
-
-  /**
-   * Amount of challenges.
-   */
-  unsigned int challenges_length;
-
-  /**
-   * Reference to a state.
-   */
-  json_t *state;
-
-  /**
-   * callback (#DispatchHandler) to call during/after operation
-   */
-  ANASTASIS_ActionCallback cb;
-
-  /**
-   * closure fpr action callback
-   */
-  void *cb_cls;
-};
-
-
 extern struct GNUNET_CURL_Context *ANASTASIS_REDUX_ctx_;
 
 
@@ -257,6 +190,26 @@ ANASTASIS_recovery_action_ (json_t *state,
                             void *cb_cls);
 
 
+/**
+ * DispatchHandler/Callback function which is called for a
+ * "enter_user_attributes" action after verifying that the
+ * arguments provided were OK and the state transition was
+ * initiated.  Begins the actual recovery logic.
+ *
+ * Returns an #ANASTASIS_ReduxAction.
+ *
+ * @param state state to operate on
+ * @param cb callback to call during/after operation
+ * @param cb_cls callback closure
+ * @return NULL
+ */
+struct ANASTASIS_ReduxAction *
+ANASTASIS_REDUX_backup_challenge_begin_ (json_t *state,
+                                         const json_t *arguments,
+                                         ANASTASIS_ActionCallback cb,
+                                         void *cb_cls);
+
+
 /**
  * Operates on a backup state depending on given #ANASTASIS_BackupState
  * and #ANASTASIS_BackupAction. The new #ANASTASIS_BackupState is returned

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