From 26af54aa831f2e84774951a5d9e0754820a26d35 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 27 Nov 2021 21:57:26 +0100 Subject: fix rendering of challenge feedback --- src/anastasis/anastasis-gtk_action.c | 577 ++++++++--------------------------- 1 file changed, 119 insertions(+), 458 deletions(-) (limited to 'src/anastasis/anastasis-gtk_action.c') diff --git a/src/anastasis/anastasis-gtk_action.c b/src/anastasis/anastasis-gtk_action.c index be0bf51..aefb379 100644 --- a/src/anastasis/anastasis-gtk_action.c +++ b/src/anastasis/anastasis-gtk_action.c @@ -1655,66 +1655,6 @@ find_challenge_by_uuid (const char *uuid) } -/** - * Find out offset of challenge with the given @a uuid in the - * "cs" array. - * - * @param[out] roff set to the offset - * @param[out] cost set to the cost of the challenge - */ -static int -get_challenge_offset (const char *uuid, - guint *roff, - struct TALER_Amount *cost) -{ - const json_t *recdoc; - const json_t *cs; - const json_t *c; - size_t off; - - recdoc = json_object_get (AG_redux_state, - "recovery_document"); - GNUNET_assert (NULL != recdoc); - cs = json_object_get (recdoc, - "cs"); - GNUNET_assert (NULL != cs); - json_array_foreach (cs, off, c) - { - const char *provider; - const char *type; - const char *u; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("type", - &type), - GNUNET_JSON_spec_string ("url", - &provider), - GNUNET_JSON_spec_string ("uuid", - &u), - GNUNET_JSON_spec_end () - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (c, - spec, - NULL, NULL)) - { - GNUNET_break (0); - continue; - } - if (0 == strcmp (uuid, - u)) - { - *roff = off; - return lookup_recovery_cost (provider, - type, - cost); - } - } - GNUNET_break (0); - return GNUNET_SYSERR; -} - - /** * Translate the @a state into a localized, human-readable * string. @@ -1734,7 +1674,7 @@ translate_state (const char *state) { .in = "payment", .out = _ ("make payment") }, { .in = "body", - .out = _ ("unexpected reply") }, + .out = _ ("fatal: unexpected reply from provider") }, { .in = "hint", .out = _ ("read hint") }, { .in = "details", @@ -1742,11 +1682,12 @@ translate_state (const char *state) { .in = "redirect", .out = _ ("open link") }, { .in = "server-failure", - .out = _ ("wait, provider failed") }, + .out = _ ("wait, Anastasis provider failed (hopefully temporary)") }, { .in = "truth-unknown", - .out = _ ("challenge unknown") }, + .out = _ ("fatal: challenge unknown to provider; " + "maybe you can solve another policy?") }, { .in = "rate-limit-exceeded", - .out = _ ("wait, tries exceeded") }, + .out = _ ("wait, tries exceeded at this time") }, { .in = "authentication-timeout", .out = _ ("awaiting completion of authentication process") }, { .in = "external-instructions", @@ -1769,187 +1710,136 @@ translate_state (const char *state) } -/** - * Test if the given @a uuid is already in @a model, - * and if so, return the position at @a iter. - * - * @param model the list store with the challenges - * @param uuid challenge UUID to look for - * @param[out] iter iter to set - * @return true if @a iter was set - */ -static bool -challenge_ls_has_uuid (GtkTreeModel *model, - const char *uuid, - GtkTreeIter *iter) -{ - GtkTreeIter pos; - - if (gtk_tree_model_get_iter_first (model, - &pos)) - do { - char *u; - - gtk_tree_model_get (model, - &pos, - AG_CSM_CHALLENGE_UUID, &u, - -1); - if (0 == strcmp (uuid, - u)) - { - g_free (u); - if (NULL != iter) - *iter = pos; - return true; - } - g_free (u); - } - while (gtk_tree_model_iter_next (model, - &pos)); - return false; -} - - /** * Update the list store with the challenge feedback. + * + * @param uuid the UUID to render feedback for + * @param builder the builder to use to grab display widgets */ static void -show_challenge_feedback (void) +show_challenge_feedback (const char *uuid, + GtkBuilder *builder) { - GtkListStore *ls; json_t *cf; const json_t *f; - const char *uuid; + const char *state; + const char *redirect_url = NULL; + const char *hint = NULL; + json_t *details = NULL; + const char *taler_pay_uri = NULL; + uint32_t ec = 0; + uint32_t http_status = 0; + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_string ("state", + &state), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_string ("taler_pay_uri", + &taler_pay_uri)), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_json ("details", + &details)), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_string ("redirect_url", + &redirect_url)), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_string ("hint", + &hint)), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_uint32 ("http_status", + &http_status)), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_uint32 ("error_code", + &ec)), + GNUNET_JSON_spec_end () + }; - ls = GTK_LIST_STORE (GCG_get_main_window_object ( - "challenge_status_liststore")); cf = json_object_get (AG_redux_state, "challenge_feedback"); - json_object_foreach (cf, uuid, f) + f = json_object_get (cf, uuid); + if (NULL == f) + return; /* no feedback */ + if (GNUNET_OK != + GNUNET_JSON_parse (f, + spec, + NULL, NULL)) { - const char *state; - const char *redirect_url = NULL; - const char *hint = NULL; - json_t *details = NULL; - const char *taler_pay_uri = NULL; - uint32_t ec = 0; - uint32_t http_status = 0; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("state", - &state), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string ("taler_pay_uri", - &taler_pay_uri)), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_json ("details", - &details)), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string ("redirect_url", - &redirect_url)), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string ("hint", - &hint)), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_uint32 ("http_status", - &http_status)), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_uint32 ("error_code", - &ec)), - GNUNET_JSON_spec_end () - }; - struct TALER_Amount cost; - guint off; - GdkPixbuf *qr = NULL; - const char *emsg = NULL; - - if (GNUNET_OK != - GNUNET_JSON_parse (f, - spec, - NULL, NULL)) - { - GNUNET_break (0); - json_dumpf (f, - stderr, - JSON_INDENT (2)); - continue; - } - if (GNUNET_OK != - get_challenge_offset (uuid, - &off, - &cost)) - { - GNUNET_break (0); - GNUNET_JSON_parse_free (spec); - continue; - } + GNUNET_break (0); + json_dumpf (f, + stderr, + JSON_INDENT (2)); + return; + } + if (0) + { + /* TODO: do we want to show the payment request here at all? */ if (NULL != taler_pay_uri) { - GtkWidget*w; + GdkPixbuf *qr; + GtkWidget *w = NULL; - w = GTK_WIDGET (GCG_get_main_window_object ( - "anastasis_gtk_challenge_status_treeview")); qr = AG_setup_qrcode (w, taler_pay_uri, strlen (taler_pay_uri)); + g_object_unref (qr); } - if (TALER_EC_NONE != ec) - emsg = TALER_ErrorCode_get_hint (ec); - if (0 == strcmp (state, - "hint")) - emsg = dgettext ("taler-exchange", - hint); - if (0 == strcmp (state, - "details")) - { - emsg = dgettext ("taler-exchange", - json_string_value (json_object_get (details, - "hint"))); - } - { - GtkTreeIter iter; - bool found; - - found = challenge_ls_has_uuid (GTK_TREE_MODEL (ls), - uuid, - &iter); - if (found) - gtk_list_store_set ( - ls, - &iter, - AG_CSM_SOLVED, 0 == strcmp (state, "solved"), - AG_CSM_STATUS, translate_state (state), - AG_CSM_PAYMENT_QR_CODE, qr, - AG_CSM_ERROR_MESSAGE, emsg, - AG_CSM_PAYTO_URI, taler_pay_uri, - AG_CSM_PAYING, NULL != taler_pay_uri, - AG_CSM_HAS_ERROR, NULL != emsg, - AG_CSM_COST, TALER_amount2s (&cost), - AG_CSM_REDIRECT_URL, redirect_url, - AG_CSM_HAVE_REDIRECT, NULL != redirect_url, - AG_CSM_NOT_SOLVED, 0 != strcmp (state, "solved"), - -1); - else - gtk_list_store_insert_with_values ( - ls, - NULL, - -1, /* append */ - AG_CSM_CHALLENGE_OFFSET, (guint) (off + 1), - AG_CSM_CHALLENGE_UUID, uuid, - AG_CSM_SOLVED, 0 == strcmp (state, "solved"), - AG_CSM_STATUS, translate_state (state), - AG_CSM_PAYMENT_QR_CODE, qr, - AG_CSM_ERROR_MESSAGE, emsg, - AG_CSM_PAYTO_URI, taler_pay_uri, - AG_CSM_PAYING, NULL != taler_pay_uri, - AG_CSM_HAS_ERROR, NULL != emsg, - AG_CSM_COST, TALER_amount2s (&cost), - AG_CSM_REDIRECT_URL, redirect_url, - AG_CSM_HAVE_REDIRECT, NULL != redirect_url, - AG_CSM_NOT_SOLVED, 0 != strcmp (state, "solved"), - -1); - GNUNET_JSON_parse_free (spec); - } } + /* Note: Eventually, we want to think about where we show the + redirect_url, if 'state' == 'redirect'; + But: redirect_url is currently not used by any provider.*/ + if (TALER_EC_NONE != ec) + { + const char *emsg; + GtkLabel *l; + + emsg = TALER_ErrorCode_get_hint (ec); + l = GTK_LABEL (gtk_builder_get_object (builder, + "error_label")); + gtk_label_set_text (l, + emsg); + gtk_widget_show (GTK_WIDGET (l)); + } + if (0 == strcmp (state, + "hint")) + { + const char *thint; + GtkLabel *l; + + thint = dgettext ("taler-exchange", + hint); + l = GTK_LABEL (gtk_builder_get_object (builder, + "hint_label")); + gtk_label_set_text (l, + thint); + gtk_widget_show (GTK_WIDGET (l)); + } + else + { + const char *hint; + GtkLabel *l; + + hint = translate_state (state); + l = GTK_LABEL (gtk_builder_get_object (builder, + "hint_label")); + gtk_label_set_text (l, + hint); + gtk_widget_show (GTK_WIDGET (l)); + } + if (0 == strcmp (state, + "details")) + { + const char *hint; + GtkLabel *l; + + hint = dgettext ("taler-exchange", + json_string_value (json_object_get (details, + "hint"))); + l = GTK_LABEL (gtk_builder_get_object (builder, + "hint_label")); + gtk_label_set_text (l, + hint); + gtk_widget_show (GTK_WIDGET (l)); + } + GNUNET_JSON_parse_free (spec); } @@ -2353,6 +2243,8 @@ add_challenge (GtkBox *challenge_box, if (NULL != icon) gtk_widget_show (GTK_WIDGET (icon)); } + show_challenge_feedback (uuid, + builder); gtk_label_set_text (label, instructions); g_object_ref (hbox); @@ -2421,7 +2313,7 @@ add_policy (GtkBox *policy_box, } GNUNET_asprintf (&txt, _ ("Policy #%u"), - (unsigned int) 1 + pindex); + (unsigned int) (1 + pindex)); gtk_label_set_text (label, txt); GNUNET_free (txt); @@ -2480,237 +2372,6 @@ action_challenge_selecting (void) policy); } } - -#if OLD - - { - json_t *challenges; - size_t index; - json_t *challenge; - GtkListStore *ls; - - ls = GTK_LIST_STORE (GCG_get_main_window_object ( - "challenge_status_liststore")); - gtk_list_store_clear (ls); - challenges = json_object_get (rd, - "cs"); - json_array_foreach (challenges, index, challenge) - { - const char *instructions; - const char *provider; - const char *type; - const char *uuid; - struct TALER_Amount cost; - bool async = false; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("instructions", - &instructions), - GNUNET_JSON_spec_string ("type", - &type), - GNUNET_JSON_spec_string ("url", - &provider), - GNUNET_JSON_spec_string ("uuid", - &uuid), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_bool ("async", - &async)), - GNUNET_JSON_spec_end () - }; - - { - const json_t *ks; - - ks = json_object_get (challenge, - "key_share"); - if ( (NULL != ks) && - (! json_is_null (ks)) ) - continue; /* already solved */ - } - if (GNUNET_OK != - GNUNET_JSON_parse (challenge, - spec, - NULL, NULL)) - { - GNUNET_break (0); - continue; - } - if (GNUNET_OK != - lookup_recovery_cost (provider, - type, - &cost)) - { - GNUNET_break (0); - continue; - } - if (challenge_ls_has_uuid (GTK_TREE_MODEL (ls), - uuid, - NULL)) - continue; - if (async && - (NULL == AG_long_task) ) - { - long_next = GNUNET_TIME_UNIT_ZERO_ABS; - AG_long_task - = GNUNET_SCHEDULER_add_now (&long_task, - NULL); - } - gtk_list_store_insert_with_values ( - ls, - NULL, - -1, /* append */ - AG_CSM_CHALLENGE_OFFSET, (guint) (index + 1), - AG_CSM_CHALLENGE_UUID, uuid, - AG_CSM_SOLVED, false, - AG_CSM_STATUS, _ ("new"), - AG_CSM_PAYMENT_QR_CODE, NULL, - AG_CSM_ERROR_MESSAGE, NULL, - AG_CSM_PAYTO_URI, NULL, - AG_CSM_PAYING, false, - AG_CSM_HAS_ERROR, false, - AG_CSM_COST, TALER_amount2s (&cost), - AG_CSM_REDIRECT_URL, NULL, - AG_CSM_HAVE_REDIRECT, false, - AG_CSM_NOT_SOLVED, true, - AG_CSM_TYPE, type, - AG_CSM_INSTRUCTIONS, instructions, - AG_CSM_PROVIDER_URL, provider, - -1); - } - } - show_challenge_feedback (); - - { - GtkTreeStore *ts; - json_t *policies; - size_t pindex; - json_t *policy; - char *summary = NULL; - - ts = GTK_TREE_STORE (GCG_get_main_window_object ( - "policy_review_treestore")); - gtk_tree_store_clear (ts); - policies = json_object_get (rd, - "dps"); - GNUNET_assert (NULL != policies); - json_array_foreach (policies, pindex, policy) - { - json_t *challenges; - size_t index; - json_t *challenge; - GtkTreeIter piter; - - gtk_tree_store_insert (ts, - &piter, - NULL, /* no parent */ - -1 /* append */); - challenges = json_object_get (policy, - "challenges"); - if (NULL == challenges) - { - GNUNET_break_op (0); - AG_error ("Policy did not parse correctly"); - return; - } - json_array_foreach (challenges, index, challenge) - { - const char *uuid = json_string_value (json_object_get (challenge, - "uuid")); - const json_t *cs; - const char *type; - const char *provider; - const char *instructions; - bool solved = false; - struct GNUNET_JSON_Specification cspec[] = { - GNUNET_JSON_spec_string ("type", - &type), - GNUNET_JSON_spec_string ("url", - &provider), - GNUNET_JSON_spec_string ("instructions", - &instructions), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_bool ("solved", - &solved)), - GNUNET_JSON_spec_end () - }; - struct TALER_Amount recovery_cost; - - GNUNET_assert (NULL != uuid); - cs = find_challenge_by_uuid (uuid); - if (NULL == cs) - { - GNUNET_break_op (0); - AG_error ("Policy did not parse correctly"); - return; - } - if (GNUNET_OK != - GNUNET_JSON_parse (cs, - cspec, - NULL, NULL)) - { - GNUNET_break_op (0); - AG_error ("Policy did not parse correctly"); - return; - } - - if (GNUNET_OK != - lookup_recovery_cost (provider, - type, - &recovery_cost)) - { - GNUNET_break_op (0); - AG_error ("Policy did not parse correctly"); - return; - } - gtk_tree_store_insert_with_values (ts, - NULL, - &piter, /* parent */ - -1, /* append */ - AG_PRMC_POLICY_NAME, - instructions, - AG_PRMC_METHOD_TYPE, - type, - AG_PRMC_COST, - TALER_amount2s (&recovery_cost), - AG_PRMC_PROVIDER_URL, - provider, - AG_PRMC_WAS_SOLVED, - solved, - -1); - if (NULL == summary) - { - summary = GNUNET_strdup (type); - } - else - { - char *tmp; - - GNUNET_asprintf (&tmp, - "%s + %s", - summary, - type); - GNUNET_free (summary); - summary = tmp; - } - } /* for each challenge */ - if (NULL != summary) - { - gtk_tree_store_set (ts, - &piter, - AG_PRMC_POLICY_NAME, summary, - -1); - GNUNET_free (summary); - } - } /* for each policy */ - } - { - GtkTreeView *tv; - - tv = GTK_TREE_VIEW (GCG_get_main_window_object ( - "anastasis_gtk_choose_policy_treeview")); - gtk_tree_view_expand_all (tv); - } -#endif - AG_sensitive ("anastasis_gtk_review_policy_treeview"); AG_show ("anastasis_gtk_progress_vbox"); AG_progress_update (); -- cgit v1.2.3