From 410068d236414064ec6fcb3cfb9560f1670671c0 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 2 Feb 2022 23:03:41 +0100 Subject: preliminary implementation of add provider button (untested) --- src/anastasis/Makefile.am | 1 + src/anastasis/anastasis-gtk.c | 16 +- src/anastasis/anastasis-gtk.h | 4 + src/anastasis/anastasis-gtk_handle-add-provider.c | 244 ++++++++++++++++++++++ 4 files changed, 257 insertions(+), 8 deletions(-) create mode 100644 src/anastasis/anastasis-gtk_handle-add-provider.c (limited to 'src') diff --git a/src/anastasis/Makefile.am b/src/anastasis/Makefile.am index 6827f8e..0d658f4 100644 --- a/src/anastasis/Makefile.am +++ b/src/anastasis/Makefile.am @@ -17,6 +17,7 @@ anastasis_gtk_SOURCES = \ anastasis-gtk_autocomplete.c \ anastasis-gtk_dispatch.c anastasis-gtk_dispatch.h \ anastasis-gtk_io.c \ + anastasis-gtk_handle-add-provider.c \ anastasis-gtk_handle-auth-delete-button-clicked.c \ anastasis-gtk_handle-auth-edit-provider-clicked.c \ anastasis-gtk_handle-backup-button-clicked.c \ diff --git a/src/anastasis/anastasis-gtk.c b/src/anastasis/anastasis-gtk.c index e3742a0..1ffc51a 100644 --- a/src/anastasis/anastasis-gtk.c +++ b/src/anastasis/anastasis-gtk.c @@ -58,7 +58,7 @@ struct GNUNET_CONTAINER_MultiHashMap *AG_entry_attributes; /** * Curl context for communication with taler backend */ -static struct GNUNET_CURL_Context *ctx; +struct GNUNET_CURL_Context *AG_ctx; /** * Handle to an ongoing action. @@ -123,10 +123,10 @@ shutdown_task (void *cls) AG_ra = NULL; } AG_stop_long_action (); - if (NULL != ctx) + if (NULL != AG_ctx) { - GNUNET_CURL_fini (ctx); - ctx = NULL; + GNUNET_CURL_fini (AG_ctx); + AG_ctx = NULL; } if (NULL != rc) { @@ -232,10 +232,10 @@ run (void *cls) GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); /* initialize HTTP client */ - ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule, - &rc); - rc = GNUNET_CURL_gnunet_rc_create (ctx); - ANASTASIS_redux_init (ctx); + AG_ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule, + &rc); + rc = GNUNET_CURL_gnunet_rc_create (AG_ctx); + ANASTASIS_redux_init (AG_ctx); if (0 != argc) AG_load (argv[0]); } diff --git a/src/anastasis/anastasis-gtk.h b/src/anastasis/anastasis-gtk.h index 54c47fb..7c2bd78 100644 --- a/src/anastasis/anastasis-gtk.h +++ b/src/anastasis/anastasis-gtk.h @@ -61,6 +61,10 @@ extern json_t *AG_redux_state; */ extern struct ANASTASIS_ReduxAction *AG_ra; +/** + * Curl context for communication with taler backend + */ +extern struct GNUNET_CURL_Context *AG_ctx; /** * State associated with a background long action. diff --git a/src/anastasis/anastasis-gtk_handle-add-provider.c b/src/anastasis/anastasis-gtk_handle-add-provider.c new file mode 100644 index 0000000..8bf68e9 --- /dev/null +++ b/src/anastasis/anastasis-gtk_handle-add-provider.c @@ -0,0 +1,244 @@ +/* + This file is part of anastasis-gtk. + Copyright (C) 2022 Anastasis SARL + + Anastasis is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + Anastasis is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Anastasis; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +/** + * @file src/anastasis/anastasis-gtk_handle-add-provider.c + * @brief Dialog to add a provider during recovery + * @author Christian Grothoff + */ +#include +#include +#include "anastasis-gtk_action.h" +#include "anastasis-gtk_helper.h" +#include +#include + +/** + * State data for the provider, NULL if none is available. + */ +static json_t *pstate; + +/** + * Current /config operation, or NULL if none. + */ +static struct ANASTASIS_ConfigOperation *co; + + +/** + * Function called with the result of a /config request. + * Note that an HTTP status of #MHD_HTTP_OK is no guarantee + * that @a acfg is non-NULL. @a acfg is non-NULL only if + * the server provided an acceptable response. + * + * @param cls closure with our `GtkBuilder *` + * @param http_status the HTTP status + * @param acfg configuration obtained, NULL if we could not parse it + */ +static void +config_cb (void *cls, + unsigned int http_status, + const struct ANASTASIS_Config *acfg) +{ + GtkBuilder *builder = GTK_BUILDER (cls); + GtkWidget *button; + json_t *methods_list; + GtkLabel *l; + + co = NULL; + l = GTK_LABEL (gtk_builder_get_object (builder, + "error_label")); + if ( (MHD_HTTP_OK != http_status) || + (NULL == acfg) ) + { + char *msg; + + if (0 == http_status) + GNUNET_asprintf (&msg, + "Provider URL invalid (no response)"); + else + GNUNET_asprintf (&msg, + "Provider URL invalid (HTTP status %u)", + http_status); + gtk_widget_show (GTK_WIDGET (l)); + gtk_label_set_text (l, + msg); + free (msg); + return; + } + methods_list = json_array (); + GNUNET_assert (NULL != methods_list); + for (unsigned int i = 0; imethods_length; i++) + { + struct ANASTASIS_AuthorizationMethodConfig *method = &acfg->methods[i]; + json_t *mj = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_string ("type", + method->type), + TALER_JSON_pack_amount ("usage_fee", + &method->usage_fee)); + + GNUNET_assert (0 == + json_array_append_new (methods_list, + mj)); + } + pstate = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_array_steal ("methods", + methods_list), + TALER_JSON_pack_amount ("annual_fee", + &acfg->annual_fee), + TALER_JSON_pack_amount ("truth_upload_fee", + &acfg->truth_upload_fee), + TALER_JSON_pack_amount ("liability_limit", + &acfg->liability_limit), + GNUNET_JSON_pack_string ("currency", + acfg->currency), + GNUNET_JSON_pack_string ("business_name", + acfg->business_name), + GNUNET_JSON_pack_uint64 ("storage_limit_in_megabytes", + acfg->storage_limit_in_megabytes), + GNUNET_JSON_pack_data_auto ("salt", + &acfg->salt), + GNUNET_JSON_pack_uint64 ("http_status", + http_status)); + button = GTK_WIDGET (gtk_builder_get_object (builder, + "add_button")); + gtk_widget_set_sensitive (button, + true); + gtk_widget_hide (GTK_WIDGET (l)); +} + + +/** + * Function called when the user edits the URL in the "add_provider" + * dialog. Updates the visibility of the 'apply/add' button. + * + * @param entry the entry that changed + * @param user_data our `GtkBuilder *` + */ +void +add_provider_url_entry_changed_cb (GtkEntry *entry, + gpointer user_data) +{ + GtkBuilder *builder = GTK_BUILDER (user_data); + GtkWidget *button; + const char *url; + + json_decref (pstate); + pstate = NULL; + if (NULL != co) + { + ANASTASIS_config_cancel (co); + co = NULL; + } + button = GTK_WIDGET (gtk_builder_get_object (builder, + "add_button")); + gtk_widget_set_sensitive (button, + false); + url = gtk_entry_get_text (entry); + if ( (0 == strncasecmp (url, + "http://", + strlen ("http://"))) || + (0 == strncasecmp (url, + "https://", + strlen ("https://"))) ) + { + co = ANASTASIS_get_config (AG_ctx, + url, + &config_cb, + builder); + GNUNET_break (NULL != co); + } +} + + +/** + * Function called from the edit-provider dialog upon completion. + * + * @param dialog the pseudonym selection dialog + * @param response_id response code from the dialog + * @param user_data the builder of the dialog + */ +void +add_provider_dialog_response_cb (GtkDialog *dialog, + gint response_id, + gpointer user_data) +{ + GtkBuilder *builder = GTK_BUILDER (user_data); + GtkEntry *entry; + const char *url; + + if (NULL != co) + { + ANASTASIS_config_cancel (co); + co = NULL; + } + if (GTK_RESPONSE_APPLY != response_id) + { + gtk_widget_destroy (GTK_WIDGET (dialog)); + g_object_unref (G_OBJECT (builder)); + json_decref (pstate); + pstate = NULL; + return; + } + entry = GTK_ENTRY (gtk_builder_get_object (builder, + "url_entry")); + url = gtk_entry_get_text (entry); + ANASTASIS_policy_discovery_more (AG_pd, + url, + pstate); + gtk_widget_destroy (GTK_WIDGET (dialog)); + g_object_unref (G_OBJECT (builder)); + json_decref (pstate); + pstate = NULL; +} + + +/** + * Callback invoked if the the "Add"-provider button is clicked. + * + * @param object + * @param user_data unused + */ +void +anastasis_gtk_add_provider_button_clicked_cb (GtkButton *object, + gpointer user_data) +{ + GtkWidget *ad; + GtkBuilder *builder; + GtkWidget *toplevel; + + if (NULL == AG_pd) + { + GNUNET_break (0); + return; + } + builder = GNUNET_GTK_get_new_builder ("anastasis_gtk_add_provider.glade", + NULL); + if (NULL == builder) + { + GNUNET_break (0); + return; + } + ad = GTK_WIDGET (gtk_builder_get_object (builder, + "add_provider_dialog")); + toplevel = gtk_widget_get_toplevel (GTK_WIDGET (object)); + gtk_window_set_transient_for (GTK_WINDOW (ad), + GTK_WINDOW (toplevel)); + gtk_window_present (GTK_WINDOW (ad)); +} -- cgit v1.2.3