summaryrefslogtreecommitdiff
path: root/src/anastasis/anastasis-gtk_action.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2022-01-30 22:08:54 +0100
committerChristian Grothoff <christian@grothoff.org>2022-01-30 22:08:54 +0100
commitcba65eea1c1a8e3113b0b659ea860f7fb91e4f18 (patch)
treecb7ebe432d24551f19ae191830e3a8b0314e164b /src/anastasis/anastasis-gtk_action.c
parent160075f3b5a8728643ae0b05948744f0be39b9e2 (diff)
downloadanastasis-gtk-cba65eea1c1a8e3113b0b659ea860f7fb91e4f18.tar.gz
anastasis-gtk-cba65eea1c1a8e3113b0b659ea860f7fb91e4f18.tar.bz2
anastasis-gtk-cba65eea1c1a8e3113b0b659ea860f7fb91e4f18.zip
get basic logic to pass again
Diffstat (limited to 'src/anastasis/anastasis-gtk_action.c')
-rw-r--r--src/anastasis/anastasis-gtk_action.c204
1 files changed, 179 insertions, 25 deletions
diff --git a/src/anastasis/anastasis-gtk_action.c b/src/anastasis/anastasis-gtk_action.c
index 6aabd19..0723c97 100644
--- a/src/anastasis/anastasis-gtk_action.c
+++ b/src/anastasis/anastasis-gtk_action.c
@@ -839,7 +839,8 @@ action_authentications_editing (void)
* @param provider URL of provider
* @param type authentication method to look for
* @param[out] method_cost cost to return
- * @return #GNUNET_OK on success
+ * @return #GNUNET_OK on success, #GNUNET_NO if
+ * the provider is down, #GNUNET_SYSERR on other failures
*/
static enum GNUNET_GenericReturnValue
lookup_recovery_cost (const char *provider,
@@ -870,6 +871,8 @@ lookup_recovery_cost (const char *provider,
}
methods = json_object_get (ap,
"methods");
+ if (NULL == methods)
+ return GNUNET_NO; /* provider down */
json_array_foreach (methods, index, method)
{
struct TALER_Amount fee;
@@ -2050,6 +2053,87 @@ long_poll_action_cb (void *cls,
/**
+ * Function called with the results of #ANASTASIS_redux_action on "sync_providers".
+ *
+ * @param cls NULL
+ * @param error_code Error code
+ * @param response new state as result or config information of a provider
+ */
+static void
+long_poll_sync_action_cb (void *cls,
+ enum TALER_ErrorCode error_code,
+ json_t *response);
+
+
+/**
+ * Schedules the "sync_providers" action.
+ *
+ * @param cls NULL
+ */
+static void
+long_poll_sync_task (void *cls)
+{
+ json_t *tspec;
+
+ (void) cls;
+ AG_long_task = NULL;
+ if (GNUNET_TIME_absolute_is_future (long_next))
+ {
+ AG_long_task = GNUNET_SCHEDULER_add_at (long_next,
+ &long_poll_sync_task,
+ cls);
+ return;
+ }
+ long_next = GNUNET_TIME_relative_to_absolute (LP_TIMEOUT);
+ tspec = GNUNET_JSON_PACK (
+ GNUNET_JSON_pack_time_rel ("timeout",
+ LP_TIMEOUT));
+ AG_long_action
+ = ANASTASIS_redux_action (AG_redux_state,
+ "sync_providers",
+ tspec,
+ &long_poll_sync_action_cb,
+ NULL);
+ json_decref (tspec);
+}
+
+
+static void
+long_poll_sync_action_cb (void *cls,
+ enum TALER_ErrorCode error_code,
+ json_t *response)
+{
+ (void) cls;
+ AG_long_action = NULL;
+ switch (error_code)
+ {
+ case TALER_EC_NONE:
+ /* continued below */
+ break;
+ case TALER_EC_ANASTASIS_REDUCER_ACTION_INVALID:
+ /* we are in sync, nothing left to do */
+ return;
+ default:
+ AG_error (_ ("sync_providers failed: %s (#%u)"),
+ TALER_ErrorCode_get_hint (error_code),
+ (unsigned int) error_code);
+ /* simply try again */
+ AG_long_task = GNUNET_SCHEDULER_add_now (&long_poll_sync_task,
+ NULL);
+ return;
+ }
+ if (NULL != AG_ra)
+ {
+ GNUNET_break (0);
+ ANASTASIS_redux_action_cancel (AG_ra);
+ }
+ AG_action_cb (NULL,
+ TALER_EC_NONE,
+ response);
+}
+
+
+/**
* Function called with the results of #ANASTASIS_redux_action on "poll_providers".
*
* @param cls NULL
@@ -2278,8 +2362,11 @@ challenge_button_clicked_cb (GObject *object,
* @param challenge_box box to expand
* @param rd our recovery document (to use)
* @param challenge the challenge to add
+ * @return #GNUNET_OK on success, #GNUNET_NO
+ * if the provider is down, #GNUNET_SYSERR on harder
+ * internal failures
*/
-static void
+static enum GNUNET_GenericReturnValue
add_challenge (GtkBox *challenge_box,
json_t *rd,
json_t *uchallenge)
@@ -2319,6 +2406,8 @@ add_challenge (GtkBox *challenge_box,
&solved)),
GNUNET_JSON_spec_end ()
};
+ bool ok = true;
+ enum GNUNET_GenericReturnValue ret;
if (GNUNET_OK !=
GNUNET_JSON_parse (uchallenge,
@@ -2326,7 +2415,7 @@ add_challenge (GtkBox *challenge_box,
NULL, NULL))
{
GNUNET_break (0);
- return;
+ return GNUNET_SYSERR;
}
{
json_t *challenges;
@@ -2346,21 +2435,30 @@ add_challenge (GtkBox *challenge_box,
NULL, NULL))
{
GNUNET_break (0);
- continue;
+ return GNUNET_SYSERR;
}
if (0 == strcmp (uuid,
iuuid))
break;
}
}
- if (GNUNET_OK !=
- lookup_recovery_cost (provider,
- type,
- &cost))
+ ret = lookup_recovery_cost (provider,
+ type,
+ &cost);
+ if (GNUNET_SYSERR == ret)
{
GNUNET_break (0);
- return;
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Could not find cost of %s at %s\n",
+ type,
+ provider);
+ json_dumpf (AG_redux_state,
+ stderr,
+ JSON_INDENT (2));
+ return GNUNET_SYSERR;
}
+ if (GNUNET_NO == ret)
+ ok = false;
builder = GNUNET_GTK_get_new_builder (
"anastasis_gtk_challenge_template.glade",
@@ -2373,6 +2471,9 @@ add_challenge (GtkBox *challenge_box,
"challenge_label"));
button = GTK_BUTTON (gtk_builder_get_object (builder,
"solve_challenge_button"));
+ if (! ok)
+ gtk_widget_set_sensitive (GTK_WIDGET (button),
+ false);
if (solved)
{
GtkImage *solved_img;
@@ -2388,8 +2489,12 @@ add_challenge (GtkBox *challenge_box,
"clicked",
G_CALLBACK (challenge_button_clicked_cb),
(void *) uuid);
- gtk_widget_set_tooltip_text (GTK_WIDGET (button),
- TALER_amount2s (&cost));
+ if (ok)
+ gtk_widget_set_tooltip_text (GTK_WIDGET (button),
+ TALER_amount2s (&cost));
+ else
+ gtk_widget_set_tooltip_text (GTK_WIDGET (button),
+ _ ("unknown"));
}
{
GtkImage *icon;
@@ -2406,8 +2511,12 @@ add_challenge (GtkBox *challenge_box,
}
show_challenge_feedback (uuid,
builder);
- gtk_label_set_text (label,
- instructions);
+ if (ok)
+ gtk_label_set_text (label,
+ instructions);
+ else
+ gtk_label_set_text (label,
+ _ ("provider down"));
g_object_ref (hbox);
gtk_container_remove (GTK_CONTAINER (window),
hbox);
@@ -2417,6 +2526,9 @@ add_challenge (GtkBox *challenge_box,
false,
false,
15);
+ if (! ok)
+ return GNUNET_NO;
+ return GNUNET_OK;
}
@@ -2428,8 +2540,9 @@ add_challenge (GtkBox *challenge_box,
* @param rd our recovery document (to use)
* @param pindex policy index (for the label)
* @param policy policy to add
+ * @return true if we should long poll "sync_providers"
*/
-static void
+static bool
add_policy (GtkBox *policy_box,
json_t *rd,
size_t pindex,
@@ -2442,6 +2555,7 @@ add_policy (GtkBox *policy_box,
GtkBox *vbox;
char *txt;
json_t *challenges;
+ bool ok;
challenges = json_object_get (policy,
"challenges");
@@ -2449,7 +2563,7 @@ add_policy (GtkBox *policy_box,
{
GNUNET_break_op (0);
AG_error ("Policy did not parse correctly");
- return;
+ return false;
}
builder = GNUNET_GTK_get_new_builder ("anastasis_gtk_policy_template.glade",
NULL);
@@ -2461,20 +2575,50 @@ add_policy (GtkBox *policy_box,
"policy_label"));
vbox = GTK_BOX (gtk_builder_get_object (builder,
"policy_vbox"));
+ ok = true;
{
size_t index;
json_t *challenge;
json_array_foreach (challenges, index, challenge)
{
- add_challenge (vbox,
- rd,
- challenge);
+ enum GNUNET_GenericReturnValue ret;
+
+ ret = add_challenge (vbox,
+ rd,
+ challenge);
+ if (GNUNET_SYSERR == ret)
+ {
+ GNUNET_break (0);
+ g_object_unref (builder);
+ GNUNET_asprintf (&txt,
+ "Failed to process challenge #%u of policy #%u",
+ (unsigned int) (1 + index),
+ (unsigned int) (1 + pindex));
+ AG_error (txt);
+ GNUNET_free (txt);
+ return false;
+ }
+ if (GNUNET_NO == ret)
+ {
+ gtk_widget_set_sensitive (GTK_WIDGET (vbox),
+ false);
+ ok = false;
+ }
}
}
- GNUNET_asprintf (&txt,
- _ ("Policy #%u"),
- (unsigned int) (1 + pindex));
+ if (ok)
+ {
+ GNUNET_asprintf (&txt,
+ _ ("Policy #%u"),
+ (unsigned int) (1 + pindex));
+ }
+ else
+ {
+ GNUNET_asprintf (&txt,
+ _ ("Policy #%u (unavailable, provider down)"),
+ (unsigned int) (1 + pindex));
+ }
gtk_label_set_text (label,
txt);
GNUNET_free (txt);
@@ -2487,6 +2631,7 @@ add_policy (GtkBox *policy_box,
false,
false,
15);
+ return ! ok;
}
@@ -2500,8 +2645,10 @@ action_challenge_selecting (void)
json_t *rd;
json_t *policies;
GtkBox *policy_box;
+ bool sp = false;
AG_hide_all_frames ();
+ AG_stop_long_action ();
rd = json_object_get (AG_redux_state,
"recovery_document");
policies = json_object_get (rd,
@@ -2527,12 +2674,19 @@ action_challenge_selecting (void)
json_array_foreach (policies, pindex, policy)
{
- add_policy (policy_box,
- rd,
- pindex,
- policy);
+ sp |= add_policy (policy_box,
+ rd,
+ pindex,
+ policy);
}
}
+ if (sp)
+ {
+ long_next = GNUNET_TIME_UNIT_ZERO_ABS;
+ GNUNET_assert (NULL == AG_long_task);
+ AG_long_task = GNUNET_SCHEDULER_add_now (&long_poll_sync_task,
+ NULL);
+ }
#if FIXME
/* FIXME: Did we loose some logic like this here for the
long-polling challenges? At least the