diff options
author | Christian Grothoff <christian@grothoff.org> | 2022-01-30 22:08:54 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2022-01-30 22:08:54 +0100 |
commit | cba65eea1c1a8e3113b0b659ea860f7fb91e4f18 (patch) | |
tree | cb7ebe432d24551f19ae191830e3a8b0314e164b /src/anastasis/anastasis-gtk_action.c | |
parent | 160075f3b5a8728643ae0b05948744f0be39b9e2 (diff) | |
download | anastasis-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.c | 204 |
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 |