[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-anastasis] branch master updated: fix diversity calculation
From: |
gnunet |
Subject: |
[taler-anastasis] branch master updated: fix diversity calculation |
Date: |
Thu, 18 Feb 2021 11:43:59 +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 0492831 fix diversity calculation
0492831 is described below
commit 0492831bfb456064477da25b04470c26ee43f96d
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Thu Feb 18 11:43:56 2021 +0100
fix diversity calculation
---
src/reducer/anastasis_api_backup_redux.c | 943 +++++++++++++++++++------------
1 file changed, 592 insertions(+), 351 deletions(-)
diff --git a/src/reducer/anastasis_api_backup_redux.c
b/src/reducer/anastasis_api_backup_redux.c
index 175061d..e3e533d 100644
--- a/src/reducer/anastasis_api_backup_redux.c
+++ b/src/reducer/anastasis_api_backup_redux.c
@@ -1,6 +1,6 @@
/*
This file is part of Anastasis
- Copyright (C) 2020 Taler Systems SA
+ Copyright (C) 2020, 2021 Taler Systems SA
Anastasis is free software; you can redistribute it and/or modify it under
the
terms of the GNU Lesser General Public License as published by the Free
Software
@@ -262,37 +262,6 @@ typedef struct ANASTASIS_ReduxAction *
void *cb_cls);
-// FIXME: this function should die
-static const char *
-get_provider_url_from_id (const char *id,
- json_t *state)
-{
- const char *key;
- json_t *method;
- json_t *methods = json_object_get (state,
- "authentication_providers");
-
- json_object_foreach (methods, key, method)
- {
- GNUNET_assert (json_is_array (method));
- json_t *method_data;
- size_t index;
-
- json_array_foreach (method, index, method_data)
- {
- json_t *provider_id = json_object_get (method_data, id);
- if (NULL == provider_id)
- continue;
-
- const char *url = json_string_value (json_object_get (provider_id,
- "provider_url"));
- return url;
- }
- }
- return NULL;
-}
-
-
/**
* Update the 'backup_state' field of @a state to @a new_backup_state.
*
@@ -333,6 +302,83 @@ ANASTASIS_backup_start (const struct
GNUNET_CONFIGURATION_Handle *cfg)
}
+/**
+ * DispatchHandler/Callback function which is called for a
+ * "add_provider" action. Adds another Anastasis provider
+ * to the list of available providers for storing information.
+ *
+ * @param state state to operate on
+ * @param arguments arguments with a provider URL to add
+ * @param cb callback (#DispatchHandler) to call during/after operation
+ * @param cb_cls callback closure
+ */
+static struct ANASTASIS_ReduxAction *
+add_provider (json_t *state,
+ const json_t *arguments,
+ ANASTASIS_ActionCallback cb,
+ void *cb_cls)
+{
+ json_t *urls;
+ json_t *tlist;
+
+ tlist = json_object_get (state,
+ "authentication_providers");
+ if (NULL == tlist)
+ {
+ tlist = json_object ();
+ GNUNET_assert (NULL != tlist);
+ GNUNET_assert (0 ==
+ json_object_set_new (state,
+ "authentication_providers",
+ tlist));
+ }
+
+ if (NULL == arguments)
+ {
+ ANASTASIS_redux_fail_ (cb,
+ cb_cls,
+ TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
+ "arguments missing");
+ return NULL;
+ }
+ urls = json_object_get (arguments,
+ "urls");
+ if (NULL == urls)
+ {
+ ANASTASIS_redux_fail_ (cb,
+ cb_cls,
+ TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
+ "'urls' missing");
+ return NULL;
+ }
+ {
+ size_t index;
+ json_t *url;
+
+ json_array_foreach (urls, index, url)
+ {
+ const char *url_str = json_string_value (url);
+
+ if (NULL == url_str)
+ {
+ ANASTASIS_redux_fail_ (cb,
+ cb_cls,
+ TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
+ "'urls' must be strings");
+ return NULL;
+ }
+ GNUNET_assert (json_object_set_new (tlist,
+ url_str,
+ json_object ()));
+ }
+ }
+ return ANASTASIS_REDUX_backup_begin_ (state,
+ arguments,
+ cb,
+ cb_cls);
+}
+
+
/**
* DispatchHandler/Callback function which is called for a
* "add_authentication" action.
@@ -350,64 +396,193 @@ add_authentication (json_t *state,
ANASTASIS_ActionCallback cb,
void *cb_cls)
{
- json_t *auth_providers = json_object_get (state,
- "authentication_providers");
+ json_t *auth_providers;
+ json_t *method;
+ const char *method_type;
- GNUNET_assert (NULL != auth_providers);
- json_t *method = json_object_get (arguments, "authentication_method");
+ auth_providers = json_object_get (state,
+ "authentication_providers");
+
+ if (NULL == auth_providers)
+ {
+ ANASTASIS_redux_fail_ (cb,
+ cb_cls,
+ TALER_EC_ANASTASIS_REDUCER_STATE_INVALID,
+ "'authentication_providers' missing");
+ return NULL;
+ }
+ method = json_object_get (arguments,
+ "authentication_method");
if (NULL == method)
{
- json_t *error = json_pack ("{s:I, s:s}",
- "code",
- (json_int_t)
- TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
- "hint",
- "Authentication method required!");
- cb (cb_cls,
- TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
- error);
+ ANASTASIS_redux_fail_ (cb,
+ cb_cls,
+ TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
+ "'authentication_method' required");
return NULL;
}
- const char *method_type = json_string_value (json_object_get (method,
- "method"));
- if (! json_object_get (auth_providers,
- method_type))
+ method_type = json_string_value (json_object_get (method,
+ "method"));
+ if (NULL == method_type)
{
- json_t *error = json_pack ("{s:I, s:s}",
- "code",
- (json_int_t)
-
TALER_EC_ANASTASIS_REDUCER_AUTHENTICATION_METHOD_NOT_SUPPORTED,
- "hint",
- "Authentication method not supported!");
- cb (cb_cls,
- TALER_EC_ANASTASIS_REDUCER_AUTHENTICATION_METHOD_NOT_SUPPORTED,
- error);
+ ANASTASIS_redux_fail_ (cb,
+ cb_cls,
+ TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
+ "'method' field must be a valid string");
return NULL;
}
if (! json_object_get (method,
"data"))
{
- json_t *error = json_pack ("{s:I, s:s}",
- "code",
- (json_int_t)
- TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
- "hint",
- "Authentication data missing!");
+ ANASTASIS_redux_fail_ (cb,
+ cb_cls,
+ TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
+ "'data' field missing for authorization method");
+ return NULL;
+ }
+ /* Check we know at least one provider that supports this method */
+ {
+ bool found = false;
+ json_t *details;
+ const char *url;
+
+ json_object_foreach (auth_providers, url, details)
+ {
+ json_t *methods;
+ json_t *method;
+ size_t index;
+
+ methods = json_object_get (details,
+ "methods");
+ if (NULL == methods)
+ {
+ GNUNET_break (0);
+ continue;
+ }
+ json_array_foreach (methods, index, method)
+ {
+ const char *name;
+
+ name = json_string_value (json_object_get (method,
+ "name"));
+ GNUNET_break (NULL != name);
+ if ( (NULL != name) &&
+ (0 == strcmp (name,
+ method_type)) )
+ {
+ found = true;
+ break;
+ }
+ }
+ if (found)
+ break;
+ }
+ if (! found)
+ {
+ ANASTASIS_redux_fail_ (cb,
+ cb_cls,
+
TALER_EC_ANASTASIS_REDUCER_AUTHENTICATION_METHOD_NOT_SUPPORTED,
+ method_type);
+ return NULL;
+ }
+ }
+
+ /* append provided method to our array */
+ {
+ json_t *auth_method_arr;
+
+ auth_method_arr = json_object_get (state,
+ "authentication_methods");
+ if (! json_is_array (auth_method_arr))
+ {
+ ANASTASIS_redux_fail_ (cb,
+ cb_cls,
+ TALER_EC_ANASTASIS_REDUCER_STATE_INVALID,
+ "'authentication_methods' must be an array");
+ return NULL;
+ }
+ if (NULL == auth_method_arr)
+ {
+ auth_method_arr = json_array ();
+ GNUNET_assert (0 == json_object_set_new (state,
+ "authentication_methods",
+ auth_method_arr));
+ }
+ GNUNET_assert (0 ==
+ json_array_append (auth_method_arr,
+ method));
cb (cb_cls,
- TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
- error);
+ TALER_EC_NONE,
+ state);
+ }
+ return NULL;
+}
+
+
+/**
+ * DispatchHandler/Callback function which is called for a
+ * "del_authentication" action.
+ * Returns an #ANASTASIS_ReduxAction if operation is async.
+ *
+ * @param state state to operate on
+ * @param arguments arguments to use for operation on state
+ * @param cb callback (#DispatchHandler) to call during/after operation
+ * @param cb_cls callback closure
+ * @return NULL
+ */
+static struct ANASTASIS_ReduxAction *
+del_authentication (json_t *state,
+ const json_t *arguments,
+ ANASTASIS_ActionCallback cb,
+ void *cb_cls)
+{
+ json_t *idx;
+ json_t *auth_method_arr;
+
+ auth_method_arr = json_object_get (state,
+ "authentication_methods");
+ if (! json_is_array (auth_method_arr))
+ {
+ ANASTASIS_redux_fail_ (cb,
+ cb_cls,
+ TALER_EC_ANASTASIS_REDUCER_STATE_INVALID,
+ "'authentication_methods' must be an array");
return NULL;
}
- json_t *auth_method_arr = json_object_get (state,
- "authentication_methods");
- if (NULL == auth_method_arr)
- auth_method_arr = json_array ();
- GNUNET_assert (json_is_array (auth_method_arr));
- GNUNET_assert (0 == json_array_append_new (auth_method_arr, method));
- GNUNET_assert (0 == json_object_set (state,
- "authentication_methods",
- auth_method_arr));
+ if (NULL == arguments)
+ {
+ ANASTASIS_redux_fail_ (cb,
+ cb_cls,
+ TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
+ "arguments missing");
+ return NULL;
+ }
+ idx = json_object_get (arguments,
+ "auth_method_index");
+ if ( (NULL == idx) ||
+ (! json_is_integer (idx)) )
+ {
+ ANASTASIS_redux_fail_ (cb,
+ cb_cls,
+ TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
+ "'auth_method_index' must be a number");
+ return NULL;
+ }
+
+ {
+ size_t index = (size_t) json_integer_value (idx);
+
+ if (0 != json_array_remove (auth_method_arr,
+ index))
+ {
+ ANASTASIS_redux_fail_ (cb,
+ cb_cls,
+
TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID_FOR_STATE,
+ "removal failed");
+ return NULL;
+ }
+ }
cb (cb_cls,
TALER_EC_NONE,
state);
@@ -415,104 +590,214 @@ add_authentication (json_t *state,
}
+/* ********************** done_authentication ******************** */
+
+/**
+ * Information for running done_authentication() logic.
+ */
struct PolicyBuilder
{
- json_t *providers;
- json_t *methods;
+ /**
+ * Financial cost of the providers selected in @e best_sel.
+ * Only valid during the go_with() function.
+ */
+ struct TALER_Amount best_cost;
+
+ /**
+ * Authentication providers available overall, from our state.
+ */
+ const json_t *providers;
+
+ /**
+ * Authentication methods available overall, from our state.
+ */
+ const json_t *methods;
+
+ /**
+ * Array of authentication policies to be computed.
+ */
json_t *policies;
- unsigned int num_methods;
- unsigned int req_methods;
+ /**
+ * Currency we are using.
+ */
+ const char *currency;
- const unsigned int *m_idx;
+ /**
+ * Array of length @e req_methods.
+ */
+ unsigned int *m_idx;
+ /**
+ * Array of length @e req_methods identifying a set of providers selected
+ * for each authentication method, while we are trying to compute the
+ * 'best' allocation of providers to authentication methods.
+ * Only valid during the go_with() function.
+ */
unsigned int *best_sel;
+ /**
+ * Error hint to return on failure. Set if @e ec is not #TALER_EC_NONE.
+ */
+ const char *hint;
+
+ /**
+ * Overall number of challenges provided by the user.
+ */
+ unsigned int num_methods;
+
+ /**
+ * Number of challenges that must be satisfied to recover the secret.
+ * Derived from the total number of challenges entered by the user.
+ */
+ unsigned int req_methods;
+
+ /**
+ * Number of different Anastasis providers selected in @e best_sel.
+ * Only valid during the go_with() function.
+ */
unsigned int best_diversity;
- struct TALER_Amount best_cost;
- const char *currency;
+ /**
+ * Error code to return, #TALER_EC_NONE on success.
+ */
+ enum TALER_ErrorCode ec;
+
};
+/**
+ * Evaluate the cost/benefit of the provider selection in @a prov_sel
+ * and if it is better then the best known one in @a pb, update @a pb.
+ *
+ * @param[in,out] pb our operational context
+ * @param[in,out] prov_sel array of req_methods provider indices to complete
+ */
static void
eval_provider_selection (struct PolicyBuilder *pb,
const unsigned int *prov_sel)
{
- bool better = true;
- unsigned int curr_diversity = 0;
struct TALER_Amount curr_cost;
+ unsigned int curr_diversity;
+ /* most hold here, as invariant passed earlier in go_with() */
GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (pb->currency,
&curr_cost));
- // calculate cost
+ /* calculate cost */
for (unsigned int i = 0; i < pb->req_methods; i++)
{
- json_t *method_obj = json_array_get (pb->methods,
- pb->m_idx[i]);
+ const json_t *method_obj = json_array_get (pb->methods,
+ pb->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,
- prov_sel[i]);
- void *provider_obj_iter = json_object_iter (provider_obj);
- const char *provider_name = json_object_iter_key (provider_obj_iter);
- struct TALER_Amount method_cost;
- json_t *provider_data = json_object_get (provider_obj, provider_name);
+ const json_t *provider_obj = json_array_get (pb->providers,
+ prov_sel[i]);
+ json_t *provider_methods = json_object_get (provider_obj,
+ "methods");
+ json_t *md;
+ size_t index;
+ bool found = false;
- 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 (&curr_cost,
- &curr_cost,
- &method_cost))
+ if (NULL == provider_methods)
{
- GNUNET_break (0);
+ pb->ec = TALER_EC_ANASTASIS_REDUCER_STATE_INVALID;
+ pb->hint = "'methods' of provider not found";
+ return;
+ }
+ json_array_foreach (provider_methods, index, md)
+ {
+ const char *name;
+ struct TALER_Amount method_cost;
+ 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 (md,
+ spec,
+ NULL, NULL))
+ {
+ pb->ec = TALER_EC_ANASTASIS_REDUCER_STATE_INVALID;
+ pb->hint = "'methods' of provider";
+ return;
+ }
+ if (0 == strcmp (name,
+ method_name))
+ {
+ if ( (GNUNET_YES !=
+ TALER_amount_cmp_currency (&curr_cost,
+ &method_cost)) ||
+ (0 >
+ TALER_amount_add (&curr_cost,
+ &curr_cost,
+ &method_cost)) )
+ {
+ GNUNET_break (0);
+ pb->ec = TALER_EC_ANASTASIS_REDUCER_STATE_INVALID;
+ pb->hint = "'usage_fee' addition failure";
+ return;
+ }
+ found = true;
+ }
+ }
+ if (! found)
+ {
+ /* Provider does not OFFER this method, combination not possible.
+ Cost is basically 'infinite', but we simply then skip this. */
return;
}
}
- // calculate provider diversity
- unsigned int *tmp_arr;
+ /* calculate provider diversity by counting number of different providers
selected */
+ curr_diversity = 0;
for (unsigned int i = 0; i < pb->req_methods; i++)
{
- for (unsigned int j = 0; j < curr_diversity; j++)
+ bool found = false;
+
+ for (unsigned int j = 0; j < i; j++)
{
- if (curr_diversity == 0)
+ if (prov_sel[i] == prov_sel[j])
{
- GNUNET_array_append (tmp_arr, curr_diversity, prov_sel[i]);
+ found = true;
break;
}
- if (tmp_arr[j] == prov_sel[i])
- break;
- GNUNET_array_append (tmp_arr, curr_diversity, prov_sel[i]);
}
+ if (! found)
+ curr_diversity++;
}
-
if (curr_diversity < pb->best_diversity)
- better = false;
- else if ((GNUNET_YES == TALER_amount_cmp_currency (&curr_cost,
- &pb->best_cost))
- && (0 < TALER_amount_cmp (&curr_cost, &pb->best_cost)))
- better = false;
-
- if (better)
- {
- memcpy (pb->best_sel,
- prov_sel,
- sizeof (unsigned int) * pb->req_methods);
- pb->best_diversity = curr_diversity;
- pb->best_cost = curr_cost;
- }
+ return;
+ if ( (GNUNET_YES ==
+ TALER_amount_cmp_currency (&curr_cost,
+ &pb->best_cost)) &&
+ (0 < TALER_amount_cmp (&curr_cost,
+ &pb->best_cost)) )
+ return;
+ memcpy (pb->best_sel,
+ prov_sel,
+ sizeof (unsigned int) * pb->req_methods);
+ pb->best_diversity = curr_diversity;
+ pb->best_cost = curr_cost;
}
+/**
+ * Recursively compute possible combination(s) of provider candidates
+ * in @e prov_sel. The selection is complete up to index @a i. Calls
+ * eval_provider_selection() upon a feasible provider selection for
+ * evaluation, resulting in "better" combinations being persisted in
+ * @a pb.
+ *
+ * @param[in,out] pb our operational context
+ * @param[in,out] prov_sel array of req_methods provider indices 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,
@@ -521,10 +806,7 @@ provider_candidate (struct PolicyBuilder *pb,
json_t *method_obj;
const char *method_name;
json_t *method_providers;
- unsigned int start = 0;
-
- if (i > 0)
- start = prov_sel[i - 1] + 1;
+ size_t num_prov;
method_obj = json_array_get (pb->methods,
pb->m_idx[i]);
@@ -532,14 +814,16 @@ provider_candidate (struct PolicyBuilder *pb,
"method"));
method_providers = json_object_get (pb->providers,
method_name);
- size_t num_prov = json_array_size (method_providers);
- for (size_t j = start; j < num_prov; j++)
+ num_prov = json_array_size (method_providers);
+ for (size_t j = 0; j < num_prov; j++)
{
prov_sel[i] = j;
if (i == pb->req_methods - 1)
{
eval_provider_selection (pb,
prov_sel);
+ if (TALER_EC_NONE != pb->ec)
+ break;
continue;
}
provider_candidate (pb,
@@ -549,29 +833,42 @@ provider_candidate (struct PolicyBuilder *pb,
}
+/**
+ * Using the selection of authentication methods from @a pb in
+ * "m_idx", compute the best choice of providers.
+ *
+ * @param[in,out] pb our operational context
+ */
static void
-go_with (struct PolicyBuilder *pb,
- const unsigned int *m_idx)
+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];
+ json_t *method_arr;
+ /* compute best provider selection (store in best_sel) */
pb->best_diversity = 0;
pb->best_sel = best_sel;
- pb->m_idx = m_idx;
-
provider_candidate (pb,
prov_sel,
0);
+ if (GNUNET_OK !=
+ TALER_amount_get_zero (pb->currency,
+ &recovery_cost))
+ {
+ pb->ec = TALER_EC_ANASTASIS_REDUCER_STATE_INVALID;
+ pb->hint = "'currency' invalid";
+ return;
+ }
- GNUNET_assert (GNUNET_OK ==
- TALER_amount_get_zero (pb->currency,
- &recovery_cost));
-
- json_t *method_arr = json_array ();
+ /* 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,
@@ -604,20 +901,34 @@ go_with (struct PolicyBuilder *pb,
return;
}
}
- json_t *policy = json_pack ("{s:o, s:o}",
- "recovery_cost",
- TALER_JSON_from_amount (&recovery_cost),
- "methods", method_arr);
- json_array_append_new (pb->policies, policy);
+ {
+ json_t *policy = json_pack ("{s:o, s:o}",
+ "recovery_cost",
+ TALER_JSON_from_amount (&recovery_cost),
+ "methods",
+ method_arr);
+ GNUNET_assert (NULL != policy);
+ GNUNET_assert (0 ==
+ json_array_append_new (pb->policies,
+ policy));
+ }
}
+/**
+ * Recursively computes all possible subsets of length "req_methods"
+ * from an array of length "num_methods", calling "go_with" on each of
+ * those subsets (in "m_idx").
+ *
+ * @param[in,out] pb our operational context
+ * @param i offset up to which the "m_idx" has been computed
+ */
static void
method_candidate (struct PolicyBuilder *pb,
- unsigned int *m_idx,
unsigned int i)
{
unsigned int start = 0;
+ unsigned int *m_idx = pb->m_idx;
if (i > 0)
start = m_idx[i - 1] + 1;
@@ -626,13 +937,11 @@ method_candidate (struct PolicyBuilder *pb,
m_idx[i] = j;
if (i == pb->req_methods - 1)
{
- go_with (pb,
- m_idx);
+ go_with (pb);
}
else
{
method_candidate (pb,
- m_idx,
i + 1);
}
}
@@ -641,8 +950,9 @@ method_candidate (struct PolicyBuilder *pb,
/**
* DispatchHandler/Callback function which is called for a
- * "done_authentication" action.
- * Returns an #ANASTASIS_ReduxAction if operation is async.
+ * "done_authentication" action. Automaticially computes policies
+ * based on available Anastasis providers and challenges provided by
+ * the user.
*
* @param state state to operate on
* @param arguments arguments to use for operation on state
@@ -656,21 +966,54 @@ done_authentication (json_t *state,
ANASTASIS_ActionCallback cb,
void *cb_cls)
{
- struct PolicyBuilder pb;
+ struct PolicyBuilder pb = {
+ .ec = TALER_EC_NONE
+ };
pb.currency = json_string_value (json_object_get (state,
"currency"));
+ if (NULL == pb.currency)
+ {
+ ANASTASIS_redux_fail_ (cb,
+ cb_cls,
+ TALER_EC_ANASTASIS_REDUCER_STATE_INVALID,
+ "'currency' must be provided");
+ return NULL;
+ }
pb.providers = json_object_get (state,
"authentication_providers");
+ if ( (NULL == pb.providers) ||
+ (! json_is_array (pb.providers) ) ||
+ (0 == json_array_size (pb.providers)) )
+ {
+ ANASTASIS_redux_fail_ (cb,
+ cb_cls,
+ TALER_EC_ANASTASIS_REDUCER_STATE_INVALID,
+ "'authentication_providers' must be provided");
+ return NULL;
+ }
pb.methods = json_object_get (state,
"authentication_methods");
+ if ( (NULL == pb.methods) ||
+ (! json_is_array (pb.methods)) )
+ {
+ ANASTASIS_redux_fail_ (cb,
+ cb_cls,
+ TALER_EC_ANASTASIS_REDUCER_STATE_INVALID,
+ "'authentication_methods' must be provided");
+ return NULL;
+ }
pb.policies = json_array ();
pb.num_methods = json_array_size (pb.methods);
switch (pb.num_methods)
{
case 0:
- // FAIL
- break;
+ json_decref (pb.policies);
+ ANASTASIS_redux_fail_ (cb,
+ cb_cls,
+ TALER_EC_ANASTASIS_REDUCER_STATE_INVALID,
+ "'authentication_methods' must not be empty");
+ return NULL;
case 1:
case 2:
pb.req_methods = pb.num_methods;
@@ -679,81 +1022,41 @@ done_authentication (json_t *state,
case 4:
pb.req_methods = pb.num_methods - 1;
break;
- default:
+ case 5:
+ case 6:
pb.req_methods = pb.num_methods - 2;
break;
+ case 7:
+ pb.req_methods = pb.num_methods - 3;
+ break;
+ default:
+ pb.req_methods = pb.num_methods / 2;
+ break;
}
{
unsigned int m_idx[pb.req_methods];
/* select req_methods from num_methods. */
+ pb.m_idx = m_idx;
method_candidate (&pb,
- m_idx,
0);
}
- GNUNET_assert (0 == json_object_set_new (state,
- "policies",
- pb.policies));
- set_state (state,
- ANASTASIS_BACKUP_STATE_POLICIES_REVIEWING);
- cb (cb_cls,
- TALER_EC_NONE,
- state);
- return NULL;
-}
-
-
-/**
- * DispatchHandler/Callback function which is called for a
- * "del_authentication" action.
- * Returns an #ANASTASIS_ReduxAction if operation is async.
- *
- * @param state state to operate on
- * @param arguments arguments to use for operation on state
- * @param cb callback (#DispatchHandler) to call during/after operation
- * @param cb_cls callback closure
- * @return NULL
- */
-static struct ANASTASIS_ReduxAction *
-del_authentication (json_t *state,
- const json_t *arguments,
- ANASTASIS_ActionCallback cb,
- void *cb_cls)
-{
- if (NULL == arguments)
- {
- json_t *error = json_pack ("{s:I, s:s}",
- "code",
- (json_int_t)
- TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
- "hint",
- "Arguments missing!");
- cb (cb_cls,
- TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
- error);
- return NULL;
- }
- size_t index = (size_t) json_integer_value (
- json_object_get (arguments,
- "auth_method_index"));
- json_t *auth_method_arr = json_object_get (state,
- "authentication_methods");
- GNUNET_assert (json_is_array (auth_method_arr));
- if (0 != json_array_remove (auth_method_arr, index))
+ if (TALER_EC_NONE != pb.ec)
{
- json_t *error = json_pack ("{s:I, s:s}",
- "code",
- (json_int_t)
-
TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID_FOR_STATE,
- "hint",
- "Operation failed");
- cb (cb_cls,
- TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID_FOR_STATE,
- error);
+ json_decref (pb.policies);
+ ANASTASIS_redux_fail_ (cb,
+ cb_cls,
+ pb.ec,
+ pb.hint);
return NULL;
}
-
+ GNUNET_assert (0 ==
+ json_object_set_new (state,
+ "policies",
+ pb.policies));
+ set_state (state,
+ ANASTASIS_BACKUP_STATE_POLICIES_REVIEWING);
cb (cb_cls,
TALER_EC_NONE,
state);
@@ -761,6 +1064,13 @@ del_authentication (json_t *state,
}
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+
/**
* DispatchHandler/Callback function which is called for a
* "add_policy" action.
@@ -780,15 +1090,10 @@ add_policy (json_t *state,
{
if (NULL == arguments)
{
- json_t *error = json_pack ("{s:I, s:s}",
- "code",
- (json_int_t)
- TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
- "hint",
- "Arguments missing!");
- cb (cb_cls,
- TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
- error);
+ ANASTASIS_redux_fail_ (cb,
+ cb_cls,
+ TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
+ "arguments missing");
return NULL;
}
@@ -809,15 +1114,10 @@ add_policy (json_t *state,
"policy");
if (! json_is_array (arg_array))
{
- json_t *error = json_pack ("{s:I, s:s}",
- "code",
- (json_int_t)
- TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
- "hint",
- "Policy is malformed!");
- cb (cb_cls,
- TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
- error);
+ ANASTASIS_redux_fail_ (cb,
+ cb_cls,
+ TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
+ "'policy' not an array");
return NULL;
}
GNUNET_assert (GNUNET_OK ==
@@ -915,15 +1215,10 @@ del_policy (json_t *state,
{
if (NULL == arguments)
{
- json_t *error = json_pack ("{s:I, s:s}",
- "code",
- (json_int_t)
- TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
- "hint",
- "Arguments missing!");
- cb (cb_cls,
- TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
- error);
+ ANASTASIS_redux_fail_ (cb,
+ cb_cls,
+ TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
+ "arguments missing");
return NULL;
}
@@ -936,15 +1231,10 @@ del_policy (json_t *state,
GNUNET_assert (json_is_array (policy_arr));
if (0 != json_array_remove (policy_arr, index))
{
- json_t *error = json_pack ("{s:I, s:s}",
- "code",
- (json_int_t)
-
TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID_FOR_STATE,
- "hint",
- "Operation failed");
- cb (cb_cls,
- TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID_FOR_STATE,
- error);
+ ANASTASIS_redux_fail_ (cb,
+ cb_cls,
+ TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID_FOR_STATE,
+ "removal failed");
return NULL;
}
cb (cb_cls,
@@ -1235,6 +1525,37 @@ initialize_payment_details (json_t *state,
}
+// FIXME: this function should die
+static const char *
+get_provider_url_from_id (const char *id,
+ json_t *state)
+{
+ const char *key;
+ json_t *method;
+ json_t *methods = json_object_get (state,
+ "authentication_providers");
+
+ json_object_foreach (methods, key, method)
+ {
+ GNUNET_assert (json_is_array (method));
+ json_t *method_data;
+ size_t index;
+
+ json_array_foreach (method, index, method_data)
+ {
+ json_t *provider_id = json_object_get (method_data, id);
+ if (NULL == provider_id)
+ continue;
+
+ const char *url = json_string_value (json_object_get (provider_id,
+ "provider_url"));
+ return url;
+ }
+ }
+ return NULL;
+}
+
+
/**
* Initialize policies for recovery document.
*
@@ -1930,16 +2251,10 @@ enter_secret (json_t *state,
if (NULL == arguments)
{
- json_t *error = json_pack ("{s:I, s:s}",
- "code",
- (json_int_t)
- TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
- "hint",
- "Arguments missing!");
- cb (cb_cls,
- TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
- error);
- json_decref (error);
+ ANASTASIS_redux_fail_ (cb,
+ cb_cls,
+ TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
+ "arguments missing");
return NULL;
}
GNUNET_assert (NULL != state);
@@ -1947,16 +2262,10 @@ enter_secret (json_t *state,
if ((NULL == json_object_get (arguments,"secret"))
|| (NULL == json_object_get (arguments, "type")))
{
- json_t *error = json_pack ("{s:I, s:s}",
- "code",
- (json_int_t)
- TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
- "hint",
- "Secret is malformed!");
- cb (cb_cls,
- TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
- error);
- json_decref (error);
+ ANASTASIS_redux_fail_ (cb,
+ cb_cls,
+ TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
+ "'secret' malformed");
return NULL;
}
GNUNET_assert (0 ==
@@ -2036,6 +2345,15 @@ pay_backup (json_t *state,
}
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+
/**
* DispatchHandler/Callback function which is called for a
* "back" action if state is "FINISHED".
@@ -2061,83 +2379,6 @@ back_finished (json_t *state,
}
-/**
- * DispatchHandler/Callback function which is called for a
- * "add_provider" action. Adds another Anastasis provider
- * to the list of available providers for storing information.
- *
- * @param state state to operate on
- * @param arguments arguments with a provider URL to add
- * @param cb callback (#DispatchHandler) to call during/after operation
- * @param cb_cls callback closure
- */
-static struct ANASTASIS_ReduxAction *
-add_provider (json_t *state,
- const json_t *arguments,
- ANASTASIS_ActionCallback cb,
- void *cb_cls)
-{
- json_t *urls;
- json_t *tlist;
-
- tlist = json_object_get (state,
- "authentication_providers");
- if (NULL == tlist)
- {
- tlist = json_object ();
- GNUNET_assert (NULL != tlist);
- GNUNET_assert (0 ==
- json_object_set_new (state,
- "authentication_providers",
- tlist));
- }
-
- if (NULL == arguments)
- {
- ANASTASIS_redux_fail_ (cb,
- cb_cls,
- TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
- "arguments missing");
- return NULL;
- }
- urls = json_object_get (arguments,
- "urls");
- if (NULL == urls)
- {
- ANASTASIS_redux_fail_ (cb,
- cb_cls,
- TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
- "'urls' missing");
- return NULL;
- }
- {
- size_t index;
- json_t *url;
-
- json_array_foreach (urls, index, url)
- {
- const char *url_str = json_string_value (url);
-
- if (NULL == url_str)
- {
- ANASTASIS_redux_fail_ (cb,
- cb_cls,
- TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
- "'urls' must be strings");
- return NULL;
- }
- GNUNET_assert (json_object_set_new (tlist,
- url_str,
- json_object ()));
- }
- }
- return ANASTASIS_REDUX_backup_begin_ (state,
- arguments,
- cb,
- 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.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [taler-anastasis] branch master updated: fix diversity calculation,
gnunet <=