/* 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++) { const 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 ("business_name", acfg->business_name), GNUNET_JSON_pack_string ("status", "enabled"), GNUNET_JSON_pack_uint64 ("http_status", MHD_HTTP_OK), GNUNET_JSON_pack_uint64 ("storage_limit_in_megabytes", acfg->storage_limit_in_megabytes), GNUNET_JSON_pack_data_auto ("provider_salt", &acfg->provider_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; json_t *ap; 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; } if (NULL == pstate) { GNUNET_break (0); return; } ap = json_object_get (AG_redux_state, "authentication_providers"); if (NULL == ap) { GNUNET_break (0); 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); GNUNET_break (0 == json_object_set_new (ap, url, pstate)); pstate = NULL; gtk_widget_destroy (GTK_WIDGET (dialog)); g_object_unref (G_OBJECT (builder)); } /** * 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)); }