gnunet-svn
[Top][All Lists]
Advanced

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

[taler-anastasis] branch master updated: clean up add/del_policy


From: gnunet
Subject: [taler-anastasis] branch master updated: clean up add/del_policy
Date: Thu, 18 Feb 2021 12:55:53 +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 00854a1  clean up add/del_policy
00854a1 is described below

commit 00854a18b5125f73469726ef3998f7c6f4a11b0a
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Thu Feb 18 12:55:51 2021 +0100

    clean up add/del_policy
---
 src/reducer/anastasis_api_backup_redux.c | 429 ++++++++++++++++++++-----------
 1 file changed, 281 insertions(+), 148 deletions(-)

diff --git a/src/reducer/anastasis_api_backup_redux.c 
b/src/reducer/anastasis_api_backup_redux.c
index e3e533d..713b153 100644
--- a/src/reducer/anastasis_api_backup_redux.c
+++ b/src/reducer/anastasis_api_backup_redux.c
@@ -606,7 +606,7 @@ struct PolicyBuilder
   /**
    * Authentication providers available overall, from our state.
    */
-  const json_t *providers;
+  json_t *providers;
 
   /**
    * Authentication methods available overall, from our state.
@@ -634,7 +634,7 @@ struct PolicyBuilder
    * 'best' allocation of providers to authentication methods.
    * Only valid during the go_with() function.
    */
-  unsigned int *best_sel;
+  const char **best_sel;
 
   /**
    * Error hint to return on failure. Set if @e ec is not #TALER_EC_NONE.
@@ -675,7 +675,7 @@ struct PolicyBuilder
  */
 static void
 eval_provider_selection (struct PolicyBuilder *pb,
-                         const unsigned int *prov_sel)
+                         const char *prov_sel[])
 {
   struct TALER_Amount curr_cost;
   unsigned int curr_diversity;
@@ -692,9 +692,9 @@ eval_provider_selection (struct PolicyBuilder *pb,
                                                pb->m_idx[i]);
     const char *method_name = json_string_value (json_object_get (method_obj,
                                                                   "method"));
-    const json_t *provider_obj = json_array_get (pb->providers,
-                                                 prov_sel[i]);
-    json_t *provider_methods = json_object_get (provider_obj,
+    const json_t *provider_cfg = json_object_get (pb->providers,
+                                                  prov_sel[i]);
+    json_t *provider_methods = json_object_get (provider_cfg,
                                                 "methods");
     json_t *md;
     size_t index;
@@ -781,7 +781,7 @@ eval_provider_selection (struct PolicyBuilder *pb,
     return;
   memcpy (pb->best_sel,
           prov_sel,
-          sizeof (unsigned int) * pb->req_methods);
+          sizeof (const char *) * pb->req_methods);
   pb->best_diversity = curr_diversity;
   pb->best_cost = curr_cost;
 }
@@ -795,29 +795,20 @@ eval_provider_selection (struct PolicyBuilder *pb,
  * @a pb.
  *
  * @param[in,out] pb our operational context
- * @param[in,out] prov_sel array of req_methods provider indices to complete
+ * @param[in,out] prov_sel array of req_methods provider URLs to complete
  * @param i index up to which @a prov_sel is already initialized
  */
 static void
 provider_candidate (struct PolicyBuilder *pb,
-                    unsigned int *prov_sel,
+                    const char *prov_sel[],
                     unsigned int i)
 {
-  json_t *method_obj;
-  const char *method_name;
-  json_t *method_providers;
-  size_t num_prov;
-
-  method_obj = json_array_get (pb->methods,
-                               pb->m_idx[i]);
-  method_name = json_string_value (json_object_get (method_obj,
-                                                    "method"));
-  method_providers = json_object_get (pb->providers,
-                                      method_name);
-  num_prov = json_array_size (method_providers);
-  for (size_t j = 0; j < num_prov; j++)
+  const char *url;
+  json_t *pconfig;
+
+  json_object_foreach (pb->providers, url, pconfig)
   {
-    prov_sel[i] = j;
+    prov_sel[i] = url;
     if (i == pb->req_methods - 1)
     {
       eval_provider_selection (pb,
@@ -844,13 +835,16 @@ go_with (struct PolicyBuilder *pb)
 {
   const unsigned int *m_idx = pb->m_idx;
   struct TALER_Amount recovery_cost;
-  unsigned int best_sel[pb->req_methods];
-  unsigned int prov_sel[pb->req_methods];
+  const char *best_sel[pb->req_methods];
+  const char *prov_sel[pb->req_methods];
   json_t *method_arr;
 
   /* compute best provider selection (store in best_sel) */
   pb->best_diversity = 0;
   pb->best_sel = best_sel;
+  memset (&pb->best_cost,
+          0,
+          sizeof (struct TALER_Amount));
   provider_candidate (pb,
                       prov_sel,
                       0);
@@ -862,49 +856,32 @@ go_with (struct PolicyBuilder *pb)
     pb->hint = "'currency' invalid";
     return;
   }
+  if (GNUNET_OK !=
+      TALER_amount_is_valid (&pb->best_cost))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Did not find providers supporting requested authorization 
methods\n");
+    return;
+  }
 
   /* Convert best_sel to entry in 'policies' array */
   method_arr = json_array ();
   GNUNET_assert (NULL != method_arr);
   for (unsigned int i = 0; i < pb->req_methods; i++)
   {
-    // FIXME: ugly!
-    json_t *method_obj = json_array_get (pb->methods,
-                                         m_idx[i]);
-    const char *method_name = json_string_value (json_object_get (method_obj,
-                                                                  "method"));
-    json_t *method_providers = json_object_get (pb->providers,
-                                                method_name);
-    json_t *provider_obj = json_array_get (method_providers,
-                                           best_sel[i]);
-    void *provider_obj_iter = json_object_iter (provider_obj);
-    const char *provider_name = json_object_iter_key (provider_obj_iter);
-    json_t *policy_method = json_pack ("{s:i, s:s}",
-                                       "authentication_method", m_idx[i],
-                                       "provider", provider_name);
-    json_array_append_new (method_arr, policy_method);
-
-    struct TALER_Amount method_cost;
-    json_t *provider_data = json_object_get (provider_obj, provider_name);
-
-    GNUNET_assert (GNUNET_OK ==
-                   TALER_string_to_amount (
-                     json_string_value (json_object_get (provider_data,
-                                                         "method_cost")),
-                     &method_cost));
-    if (0 >
-        TALER_amount_add (&recovery_cost,
-                          &recovery_cost,
-                          &method_cost))
-    {
-      GNUNET_break (0);
-      return;
-    }
+    json_t *policy_method = json_pack ("{s:I, s:s}",
+                                       "authentication_method",
+                                       (json_int_t) m_idx[i],
+                                       "provider",
+                                       best_sel[i]);
+    GNUNET_assert (0 ==
+                   json_array_append_new (method_arr,
+                                          policy_method));
   }
   {
     json_t *policy = json_pack ("{s:o, s:o}",
                                 "recovery_cost",
-                                TALER_JSON_from_amount (&recovery_cost),
+                                TALER_JSON_from_amount (&pb->best_cost),
                                 "methods",
                                 method_arr);
     GNUNET_assert (NULL != policy);
@@ -983,8 +960,7 @@ done_authentication (json_t *state,
   pb.providers = json_object_get (state,
                                   "authentication_providers");
   if ( (NULL == pb.providers) ||
-       (! json_is_array (pb.providers) ) ||
-       (0 == json_array_size (pb.providers)) )
+       (! json_is_object (pb.providers) ) )
   {
     ANASTASIS_redux_fail_ (cb,
                            cb_cls,
@@ -1064,17 +1040,12 @@ done_authentication (json_t *state,
 }
 
 
-///////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////
+/* ******************** add_policy ******************* */
 
 
 /**
  * DispatchHandler/Callback function which is called for a
  * "add_policy" action.
- * Returns an #ANASTASIS_ReduxAction if operation is async.
  *
  * @param state state to operate on
  * @param arguments arguments to use for operation on state
@@ -1088,6 +1059,14 @@ add_policy (json_t *state,
             ANASTASIS_ActionCallback cb,
             void *cb_cls)
 {
+  const json_t *arg_array;
+  json_t *policies;
+  const json_t *auth_providers;
+  const json_t *auth_methods;
+  json_t *methods;
+  struct TALER_Amount recovery_cost;
+  const char *currency;
+
   if (NULL == arguments)
   {
     ANASTASIS_redux_fail_ (cb,
@@ -1096,22 +1075,8 @@ add_policy (json_t *state,
                            "arguments missing");
     return NULL;
   }
-
-  size_t index;
-  json_t *method;
-  struct TALER_Amount recovery_cost;
-  json_t *methods = json_array ();
-
-  GNUNET_assert (json_is_array (methods));
-  json_t *policy = json_object ();
-
-  GNUNET_assert (NULL != policy);
-  json_t *policies = json_object_get (state,
-                                      "policies");
-
-  GNUNET_assert (json_is_array (policies));
-  json_t *arg_array = json_object_get (arguments,
-                                       "policy");
+  arg_array = json_object_get (arguments,
+                               "policy");
   if (! json_is_array (arg_array))
   {
     ANASTASIS_redux_fail_ (cb,
@@ -1120,74 +1085,215 @@ add_policy (json_t *state,
                            "'policy' not an array");
     return NULL;
   }
-  GNUNET_assert (GNUNET_OK ==
-                 TALER_amount_get_zero (
-                   json_string_value (json_object_get (state,
-                                                       "currency")),
-                   &recovery_cost));
+  policies = json_object_get (state,
+                              "policies");
+  if (! json_is_array (policies))
+  {
+    ANASTASIS_redux_fail_ (cb,
+                           cb_cls,
+                           TALER_EC_ANASTASIS_REDUCER_STATE_INVALID,
+                           "'policies' not an array");
+    return NULL;
+  }
+  currency = json_string_value (json_object_get (state,
+                                                 "currency"));
+  if ( (NULL == currency) ||
+       (GNUNET_OK !=
+        TALER_amount_get_zero (currency,
+                               &recovery_cost)) )
+  {
+    ANASTASIS_redux_fail_ (cb,
+                           cb_cls,
+                           TALER_EC_ANASTASIS_REDUCER_STATE_INVALID,
+                           "'currency' must be a vaild currency");
+    return NULL;
+  }
+  auth_providers = json_object_get (state,
+                                    "authentication_providers");
+  if (! json_is_object (auth_providers))
+  {
+    ANASTASIS_redux_fail_ (cb,
+                           cb_cls,
+                           TALER_EC_ANASTASIS_REDUCER_STATE_INVALID,
+                           "'auth_providers' not an object");
+    return NULL;
+  }
+  auth_methods = json_object_get (state,
+                                  "authentication_methods");
+  if (! json_is_array (auth_methods))
+  {
+    ANASTASIS_redux_fail_ (cb,
+                           cb_cls,
+                           TALER_EC_ANASTASIS_REDUCER_STATE_INVALID,
+                           "'auth_methods' not an array");
+    return NULL;
+  }
 
-  json_array_foreach (arg_array, index, method)
+  methods = json_array ();
+  GNUNET_assert (NULL != methods);
+
+  /* Add all methods from 'arg_array' to 'methods', and sum up 'recovery_cost' 
*/
   {
-    struct TALER_Amount method_cost;
-    size_t provider_index;
-    json_t *provider;
-    json_t *auth_method_arr = json_object_get (state,
-                                               "authentication_methods");
+    size_t index;
+    json_t *method;
 
-    GNUNET_assert (json_is_array (auth_method_arr));
-    size_t index = json_integer_value (json_object_get (method,
-                                                        "auth_method_index"));
+    json_array_foreach (arg_array, index, method)
+    {
+      const char *provider_url;
+      uint32_t method_idx;
+      const json_t *prov_methods;
+      const char *method_type;
 
-    const char *method_type = json_string_value (json_array_get (
-                                                   auth_method_arr,
-                                                   index));
+      struct GNUNET_JSON_Specification spec[] = {
+        GNUNET_JSON_spec_string ("provider",
+                                 &provider_url),
+        GNUNET_JSON_spec_uint32 ("auth_method_index",
+                                 &method_idx),
+        GNUNET_JSON_spec_end ()
+      };
+      if (GNUNET_OK !=
+          GNUNET_JSON_parse (method,
+                             spec,
+                             NULL, NULL))
+      {
+        json_decref (methods);
+        ANASTASIS_redux_fail_ (cb,
+                               cb_cls,
+                               TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
+                               "'method' details malformed");
+        return NULL;
+      }
 
-    const char *provider_id = json_string_value (json_object_get (method,
-                                                                  "provider"));
+      {
+        const json_t *prov_cfg;
+        prov_cfg = json_object_get (auth_providers,
+                                    provider_url);
+        if (NULL == prov_cfg)
+        {
+          json_decref (methods);
+          ANASTASIS_redux_fail_ (cb,
+                                 cb_cls,
+                                 TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
+                                 "provider URL unknown");
+          return NULL;
+        }
+        prov_methods = json_object_get (prov_cfg,
+                                        "methods");
+        if (! json_is_array (prov_methods))
+        {
+          json_decref (methods);
+          ANASTASIS_redux_fail_ (cb,
+                                 cb_cls,
+                                 TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
+                                 "provider lacks authentication methods");
+          return NULL;
+        }
+      }
 
-    json_t *auth_provider_arr = json_object_get (json_object_get (state,
-                                                                  
"authentication_providers"),
-                                                 method_type);
+      {
+        const json_t *auth_method;
+
+        auth_method = json_array_get (auth_methods,
+                                      method_idx);
+        if (NULL == auth_method)
+        {
+          json_decref (methods);
+          ANASTASIS_redux_fail_ (cb,
+                                 cb_cls,
+                                 TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
+                                 "authentication method unknown");
+          return NULL;
+        }
+        method_type = json_string_value (json_object_get (auth_method,
+                                                          "method"));
+        if (NULL == method_type)
+        {
+          json_decref (methods);
+          ANASTASIS_redux_fail_ (cb,
+                                 cb_cls,
+                                 TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
+                                 "authentication method must be a string");
+          return NULL;
+        }
+      }
 
-    GNUNET_assert (json_is_array (auth_provider_arr));
-    json_array_foreach (auth_provider_arr, provider_index, provider)
-    {
-      json_t *provider_data;
-      if (NULL != (provider_data = json_object_get (provider,
-                                                    provider_id)))
       {
-        GNUNET_assert (GNUNET_OK ==
-                       TALER_string_to_amount (
-                         json_string_value (json_object_get (provider_data,
-                                                             "method_cost")),
-                         &method_cost));
-        if (0 >
-            TALER_amount_add (&recovery_cost,
-                              &recovery_cost,
-                              &method_cost))
+        bool found = false;
+        size_t index;
+        json_t *pm;
+        json_array_foreach (prov_methods, index, pm)
         {
-          GNUNET_break (0);
+          struct TALER_Amount method_cost;
+          const char *name;
+
+          struct GNUNET_JSON_Specification spec[] = {
+            GNUNET_JSON_spec_string ("name",
+                                     &name),
+            TALER_JSON_spec_amount ("usage_fee",
+                                    &method_cost),
+            GNUNET_JSON_spec_end ()
+          };
+
+          if (GNUNET_OK !=
+              GNUNET_JSON_parse (pm,
+                                 spec,
+                                 NULL, NULL))
+          {
+            json_decref (methods);
+            ANASTASIS_redux_fail_ (cb,
+                                   cb_cls,
+                                   TALER_EC_ANASTASIS_REDUCER_STATE_INVALID,
+                                   "provider authentication method 
specification invalid");
+            return NULL;
+          }
+          if (0 != strcmp (name,
+                           method_type))
+            continue;
+          if (0 >
+              TALER_amount_add (&recovery_cost,
+                                &recovery_cost,
+                                &method_cost))
+          {
+            GNUNET_break (0);
+            ANASTASIS_redux_fail_ (cb,
+                                   cb_cls,
+                                   TALER_EC_ANASTASIS_REDUCER_STATE_INVALID,
+                                   "cost addition failed");
+            return NULL;
+          }
+          found = true;
+          break;
+        }
+        if (! found)
+        {
+          json_decref (methods);
+          ANASTASIS_redux_fail_ (cb,
+                                 cb_cls,
+                                 TALER_EC_ANASTASIS_REDUCER_STATE_INVALID,
+                                 "selected provider does not support 
authentication method");
           return NULL;
         }
-        json_decref (provider_data);
-        break;
       }
-    }
-    json_decref (auth_provider_arr);
-    json_array_append_new (methods,
-                           json_pack ("{s:I, s:s}",
-                                      "authentication_method",
-                                      (json_int_t) index,
-                                      "provider",
-                                      provider_id));
-  }
-  policy = json_pack ("{s:o, s:o}",
-                      "recovery_cost",
-                      TALER_JSON_from_amount (&recovery_cost),
-                      "methods",
-                      methods);
-  json_array_append_new (policies,
-                         policy);
+      GNUNET_assert (0 ==
+                     json_array_append (methods,
+                                        method));
+    } /* end of json_array_foreach (arg_array, index, method) */
+  }
+
+  /* add new policy to array of existing policies */
+  {
+    json_t *policy;
+
+    policy = json_pack ("{s:o, s:o}",
+                        "recovery_cost",
+                        TALER_JSON_from_amount (&recovery_cost),
+                        "methods",
+                        methods);
+    GNUNET_assert (NULL != policy);
+    GNUNET_assert (0 ==
+                   json_array_append_new (policies,
+                                          policy));
+  }
 
   cb (cb_cls,
       TALER_EC_NONE,
@@ -1196,10 +1302,12 @@ add_policy (json_t *state,
 }
 
 
+/* ******************** del_policy ******************* */
+
+
 /**
  * DispatchHandler/Callback function which is called for a
  * "del_policy" action.
- * Returns an #ANASTASIS_ReduxAction if operation is async.
  *
  * @param state state to operate on
  * @param arguments arguments to use for operation on state
@@ -1213,6 +1321,10 @@ del_policy (json_t *state,
             ANASTASIS_ActionCallback cb,
             void *cb_cls)
 {
+  const json_t *idx;
+  size_t index;
+  json_t *policy_arr;
+
   if (NULL == arguments)
   {
     ANASTASIS_redux_fail_ (cb,
@@ -1221,15 +1333,29 @@ del_policy (json_t *state,
                            "arguments missing");
     return NULL;
   }
-
-  size_t index = (size_t) json_integer_value (
-    json_object_get (arguments,
-                     "policy_index"));
-  json_t *policy_arr = json_object_get (state,
-                                        "policies");
-
-  GNUNET_assert (json_is_array (policy_arr));
-  if (0 != json_array_remove (policy_arr, index))
+  idx = json_object_get (arguments,
+                         "policy_index");
+  if (! json_is_integer (idx))
+  {
+    ANASTASIS_redux_fail_ (cb,
+                           cb_cls,
+                           TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
+                           "'policy_index' must be an integer");
+    return NULL;
+  }
+  index = json_integer_value (idx);
+  policy_arr = json_object_get (state,
+                                "policies");
+  if (! json_is_array (policy_arr))
+  {
+    ANASTASIS_redux_fail_ (cb,
+                           cb_cls,
+                           TALER_EC_ANASTASIS_REDUCER_STATE_INVALID,
+                           "'policies' must be an array");
+    return NULL;
+  }
+  if (0 != json_array_remove (policy_arr,
+                              index))
   {
     ANASTASIS_redux_fail_ (cb,
                            cb_cls,
@@ -1244,6 +1370,13 @@ del_policy (json_t *state,
 }
 
 
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+
 /**
  * Initialize data for #ANASTASIS_truth_upload.
  *

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