diff options
-rw-r--r-- | contrib/anastasis_gtk_edit_providers.glade | 160 | ||||
-rw-r--r-- | m4/libtool.m4 | 4 | ||||
-rw-r--r-- | po/POTFILES.in | 7 | ||||
-rw-r--r-- | src/anastasis/anastasis-gtk_handle-auth-edit-provider-clicked.c | 222 | ||||
-rw-r--r-- | src/anastasis/anastasis-gtk_helper.h | 33 |
5 files changed, 352 insertions, 74 deletions
diff --git a/contrib/anastasis_gtk_edit_providers.glade b/contrib/anastasis_gtk_edit_providers.glade index 5f520fa..7ca358c 100644 --- a/contrib/anastasis_gtk_edit_providers.glade +++ b/contrib/anastasis_gtk_edit_providers.glade @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.38.2 +<!-- Generated with glade 3.22.2 Copyright (C) 2019-2021 Anastasis SARL @@ -22,7 +22,7 @@ Author: Christian Grothoff --> <interface> - <requires lib="gtk+" version="3.6"/> + <requires lib="gtk+" version="3.8"/> <!-- interface-license-type lgplv3 --> <!-- interface-name Anastasis-gtk --> <!-- interface-copyright 2019-2021 Anastasis SARL --> @@ -35,33 +35,52 @@ Author: Christian Grothoff <column type="gchararray"/> <!-- column-name status_color --> <column type="gchararray"/> + <!-- column-name liability_limit --> + <column type="gchararray"/> + <!-- column-name enabled --> + <column type="gboolean"/> + <!-- column-name sensitive --> + <column type="gboolean"/> + <!-- column-name not_sensitive --> + <column type="gboolean"/> </columns> </object> <object class="GtkDialog" id="edit_provider_dialog"> - <property name="can-focus">False</property> + <property name="can_focus">False</property> <property name="modal">True</property> - <property name="window-position">center</property> - <property name="type-hint">dialog</property> + <property name="window_position">center</property> + <property name="type_hint">dialog</property> <signal name="response" handler="edit_provider_dialog_response_cb" swapped="no"/> + <child type="titlebar"> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Add Anastasis provider</property> + </object> + </child> + <action-widgets> + <action-widget response="-6">cancel_button</action-widget> + <action-widget response="-10">close_button</action-widget> + </action-widgets> <child internal-child="vbox"> <object class="GtkBox"> <property name="visible">True</property> - <property name="can-focus">False</property> + <property name="can_focus">False</property> <property name="orientation">vertical</property> <property name="spacing">2</property> <child internal-child="action_area"> <object class="GtkButtonBox"> <property name="visible">True</property> - <property name="can-focus">False</property> - <property name="layout-style">end</property> + <property name="can_focus">False</property> + <property name="layout_style">end</property> <child> <object class="GtkButton" id="cancel_button"> <property name="label">gtk-cancel</property> <property name="visible">True</property> - <property name="can-focus">False</property> - <property name="receives-default">False</property> - <property name="use-stock">True</property> - <property name="always-show-image">True</property> + <property name="can_focus">False</property> + <property name="receives_default">False</property> + <property name="use_stock">True</property> + <property name="always_show_image">True</property> </object> <packing> <property name="expand">True</property> @@ -73,10 +92,10 @@ Author: Christian Grothoff <object class="GtkButton" id="close_button"> <property name="label">gtk-apply</property> <property name="visible">True</property> - <property name="can-focus">False</property> - <property name="receives-default">False</property> - <property name="use-stock">True</property> - <property name="always-show-image">True</property> + <property name="can_focus">False</property> + <property name="receives_default">False</property> + <property name="use_stock">True</property> + <property name="always_show_image">True</property> </object> <packing> <property name="expand">True</property> @@ -94,17 +113,17 @@ Author: Christian Grothoff <child> <object class="GtkBox"> <property name="visible">True</property> - <property name="can-focus">True</property> + <property name="can_focus">True</property> <property name="orientation">vertical</property> <child> <object class="GtkBox"> <property name="visible">True</property> - <property name="can-focus">True</property> + <property name="can_focus">True</property> <child> <object class="GtkLabel"> <property name="visible">True</property> - <property name="can-focus">False</property> - <property name="margin-left">10</property> + <property name="can_focus">False</property> + <property name="margin_left">10</property> <property name="label" translatable="yes">Provider URL:</property> </object> <packing> @@ -117,15 +136,15 @@ Author: Christian Grothoff <child> <object class="GtkEntry" id="url_entry"> <property name="visible">True</property> - <property name="can-focus">True</property> - <property name="has-focus">True</property> - <property name="is-focus">True</property> - <property name="activates-default">True</property> - <property name="width-chars">54</property> - <property name="primary-icon-stock">gtk-edit</property> - <property name="secondary-icon-activatable">False</property> - <property name="secondary-icon-sensitive">False</property> - <property name="placeholder-text" translatable="yes">https://</property> + <property name="can_focus">True</property> + <property name="has_focus">True</property> + <property name="is_focus">True</property> + <property name="activates_default">True</property> + <property name="width_chars">54</property> + <property name="primary_icon_stock">gtk-edit</property> + <property name="secondary_icon_activatable">False</property> + <property name="secondary_icon_sensitive">False</property> + <property name="placeholder_text" translatable="yes">https://</property> <signal name="changed" handler="url_entry_changed_cb" swapped="no"/> </object> <packing> @@ -140,11 +159,11 @@ Author: Christian Grothoff <property name="label">gtk-add</property> <property name="visible">True</property> <property name="sensitive">False</property> - <property name="can-focus">False</property> - <property name="can-default">True</property> - <property name="has-default">True</property> - <property name="receives-default">True</property> - <property name="use-stock">True</property> + <property name="can_focus">False</property> + <property name="can_default">True</property> + <property name="has_default">True</property> + <property name="receives_default">True</property> + <property name="use_stock">True</property> <signal name="clicked" handler="url_add_button_clicked_cb" swapped="no"/> </object> <packing> @@ -164,36 +183,56 @@ Author: Christian Grothoff <child> <object class="GtkBox"> <property name="visible">True</property> - <property name="can-focus">False</property> + <property name="can_focus">False</property> <child> <object class="GtkFrame"> <property name="visible">True</property> - <property name="can-focus">False</property> - <property name="margin-top">10</property> - <property name="label-xalign">0</property> - <property name="shadow-type">none</property> + <property name="can_focus">False</property> + <property name="margin_top">10</property> + <property name="label_xalign">0</property> + <property name="shadow_type">none</property> <child> <object class="GtkAlignment"> <property name="visible">True</property> - <property name="can-focus">False</property> - <property name="left-padding">12</property> + <property name="can_focus">False</property> + <property name="left_padding">12</property> <child> <object class="GtkViewport"> <property name="visible">True</property> - <property name="can-focus">False</property> + <property name="can_focus">False</property> <child> <object class="GtkTreeView" id="provider_tree_view"> - <property name="height-request">300</property> + <property name="height_request">300</property> <property name="visible">True</property> - <property name="can-focus">False</property> + <property name="can_focus">False</property> <property name="model">provider_liststore</property> + <signal name="button-press-event" handler="provider_tree_view_button_press_event_cb" swapped="no"/> <child internal-child="selection"> <object class="GtkTreeSelection"> <property name="mode">browse</property> </object> </child> <child> - <object class="GtkTreeViewColumn"> + <object class="GtkTreeViewColumn" id="enabled_column"> + <property name="spacing">5</property> + <property name="title" translatable="yes">Use</property> + <property name="reorderable">True</property> + <property name="sort_indicator">True</property> + <property name="sort_column_id">6</property> + <child> + <object class="GtkCellRendererToggle" id="use_toggle"/> + <attributes> + <attribute name="sensitive">5</attribute> + <attribute name="activatable">5</attribute> + <attribute name="active">4</attribute> + <attribute name="inconsistent">6</attribute> + </attributes> + </child> + </object> + </child> + <child> + <object class="GtkTreeViewColumn" id="url_column"> + <property name="spacing">5</property> <property name="sizing">autosize</property> <property name="title" translatable="yes">URL</property> <child> @@ -205,8 +244,26 @@ Author: Christian Grothoff </object> </child> <child> + <object class="GtkTreeViewColumn" id="liability_column"> + <property name="spacing">5</property> + <property name="sizing">autosize</property> + <property name="title" translatable="yes">Liability limit</property> + <child> + <object class="GtkCellRendererText" id="liability_limit_text"/> + <attributes> + <attribute name="visible">7</attribute> + <attribute name="text">3</attribute> + </attributes> + </child> + </object> + </child> + <child> <object class="GtkTreeViewColumn"> + <property name="spacing">5</property> <property name="title" translatable="yes">Status</property> + <property name="reorderable">True</property> + <property name="sort_indicator">True</property> + <property name="sort_column_id">6</property> <child> <object class="GtkCellRendererText" id="status"/> <attributes> @@ -225,7 +282,7 @@ Author: Christian Grothoff <child type="label"> <object class="GtkLabel"> <property name="visible">True</property> - <property name="can-focus">False</property> + <property name="can_focus">False</property> <property name="label" translatable="yes">Known providers</property> <attributes> <attribute name="weight" value="bold"/> @@ -260,16 +317,5 @@ Author: Christian Grothoff <action-widget response="-6">cancel_button</action-widget> <action-widget response="-10">close_button</action-widget> </action-widgets> - <child type="titlebar"> - <object class="GtkLabel"> - <property name="visible">True</property> - <property name="can-focus">False</property> - <property name="label" translatable="yes">Add Anastasis provider</property> - </object> - </child> - <action-widgets> - <action-widget response="-6">cancel_button</action-widget> - <action-widget response="-10">close_button</action-widget> - </action-widgets> </object> </interface> diff --git a/m4/libtool.m4 b/m4/libtool.m4 index c4c0294..a6d21ae 100644 --- a/m4/libtool.m4 +++ b/m4/libtool.m4 @@ -1071,11 +1071,11 @@ _LT_EOF # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in - 10.0,*86*-darwin8*|10.0,*-darwin[[912]]*) + 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; 10.[[012]][[,.]]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; - 10.*|11.*) + 10.*) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; diff --git a/po/POTFILES.in b/po/POTFILES.in index 3483ced..a0f8ff8 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -26,10 +26,13 @@ src/anastasis/anastasis-gtk_handle-method-iban.c src/anastasis/anastasis-gtk_handle-method-post.c src/anastasis/anastasis-gtk_handle-method-question.c src/anastasis/anastasis-gtk_handle-method-sms.c +src/anastasis/anastasis-gtk_handle-method-totp.c src/anastasis/anastasis-gtk_handle-method-video.c src/anastasis/anastasis-gtk_handle-payqr-selection-changed.c src/anastasis/anastasis-gtk_handle-policy-activate.c +src/anastasis/.#anastasis-gtk_handle-policy-button.c src/anastasis/anastasis-gtk_handle-policy-button.c +src/anastasis/.#anastasis-gtk_handle-policy-meta.c src/anastasis/anastasis-gtk_handle-policy-meta.c src/anastasis/anastasis-gtk_handle-policy-version-changed.c src/anastasis/anastasis-gtk_handle-recovery-button-clicked.c @@ -42,16 +45,17 @@ src/anastasis/anastasis-gtk_pe-delete-policy.c src/anastasis/anastasis-gtk_pe-edit-policy.c src/anastasis/anastasis-gtk_progress.c src/anastasis/os_installation.c -contrib/anastasis_gtk_about_window.glade contrib/anastasis_gtk_auth_add_email.glade contrib/anastasis_gtk_auth_add_iban.glade contrib/anastasis_gtk_auth_add_post.glade contrib/anastasis_gtk_auth_add_question.glade contrib/anastasis_gtk_auth_add_sms.glade +contrib/anastasis_gtk_auth_add_totp.glade contrib/anastasis_gtk_auth_add_video.glade contrib/anastasis_gtk_challenge_code.glade contrib/anastasis_gtk_challenge_iban.glade contrib/anastasis_gtk_challenge_question.glade +contrib/anastasis_gtk_challenge_totp.glade contrib/anastasis_gtk_edit_policy.glade contrib/anastasis_gtk_edit_providers.glade contrib/anastasis_gtk_main_window.glade @@ -59,4 +63,5 @@ contrib/anastasis_gtk_open_file_dialog.glade contrib/anastasis_gtk_open_secret_dialog.glade contrib/anastasis_gtk_save_file_dialog.glade contrib/anastasis_gtk_save_secret_dialog.glade +contrib/anastasis_gtk_warn_multifactor.glade contrib/this_stays_private.glade diff --git a/src/anastasis/anastasis-gtk_handle-auth-edit-provider-clicked.c b/src/anastasis/anastasis-gtk_handle-auth-edit-provider-clicked.c index 591a23f..fdff487 100644 --- a/src/anastasis/anastasis-gtk_handle-auth-edit-provider-clicked.c +++ b/src/anastasis/anastasis-gtk_handle-auth-edit-provider-clicked.c @@ -33,6 +33,180 @@ #include <microhttpd.h> + +/** + * Context for menu callbacks. + */ +struct MenuContext +{ + /** + * Base URL of the selected provider. + */ + char *url; + +}; + + +/** + * An item was selected from the context menu; destroy the menu shell. + * + * @param menushell menu to destroy + * @param user_data the 'struct MenuContext' of the menu + */ +static void +context_popup_selection_done (GtkMenuShell *menushell, + gpointer user_data) +{ + struct MenuContext *ctx = user_data; + + gtk_widget_destroy (GTK_WIDGET (menushell)); + GNUNET_free (ctx->url); + GNUNET_free (ctx); +} + + +/** + * The user selected the 'view pp' menu. + * + * @param menuitem the selected menu + * @param user_data a `struct MenuContext` + */ +static void +view_terms_of_service (GtkMenuItem *menuitem, + gpointer user_data) +{ + struct MenuContext *ctx = user_data; + GNUNET_break (0); // FIXME: not implemented + +} + + +/** + * The user selected the 'view tos' menu. + * + * @param menuitem the selected menu + * @param user_data a `struct MenuContext` + */ +static void +view_privacy_policy (GtkMenuItem *menuitem, + gpointer user_data) +{ + struct MenuContext *ctx = user_data; + + + GNUNET_break (0); // FIXME: not implemented +} + + +/** + * User clicked on the tree view. If it was a right-click, show + * context menu to allow user to view PP or TOS. + * + * @param widget the tree view + * @param event the event + * @param user_data the builder + */ +gboolean +provider_tree_view_button_press_event_cb (GtkWidget *widget, + GdkEvent *event, + gpointer user_data) +{ + GtkBuilder *builder = GTK_BUILDER (user_data); + GdkEventButton *event_button = (GdkEventButton *) event; + GtkTreeView *tv; + GtkTreeModel *tm; + GtkTreePath *path; + GtkTreeIter iter; + struct MenuContext *ctx; + GtkMenu *menu; + + if ((GDK_BUTTON_PRESS != event->type) || + (3 != event_button->button)) + return FALSE; /* not a right-click */ + tm = GTK_TREE_MODEL (gtk_builder_get_object (builder, + "provider_liststore")); + if (NULL == tm) + { + GNUNET_break (0); + return FALSE; + } + tv = GTK_TREE_VIEW (GCG_get_main_window_object ( + "provider_tree_view")); + if (! gtk_tree_view_get_path_at_pos (tv, + event_button->x, + event_button->y, + &path, + NULL, + NULL, + NULL)) + { + /* nothing selected */ + return FALSE; + } + if (! gtk_tree_model_get_iter (tm, + &iter, + path)) + { + /* not sure how we got a path but no iter... */ + GNUNET_break (0); + return FALSE; + } + gtk_tree_path_free (path); + ctx = GNUNET_new (struct MenuContext); + gtk_tree_model_get (tm, + &iter, + AG_PMC_PROVIDER_URL, &ctx->url, + -1); + menu = GTK_MENU (gtk_menu_new ()); + { + GtkWidget *child; + + child = gtk_menu_item_new_with_label (_ ("View _privacy policy...")); + g_signal_connect (child, + "activate", + G_CALLBACK (&view_privacy_policy), + ctx); + gtk_label_set_use_underline (GTK_LABEL ( + gtk_bin_get_child (GTK_BIN (child))), + TRUE); + gtk_widget_show (child); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), + child); + } + { + GtkWidget *child; + + child = gtk_menu_item_new_with_label (_("View _terms of service...")); + g_signal_connect (child, + "activate", + G_CALLBACK (&view_terms_of_service), + ctx); + gtk_label_set_use_underline (GTK_LABEL ( + gtk_bin_get_child (GTK_BIN (child))), + TRUE); + gtk_widget_show (child); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), + child); + } + + g_signal_connect (menu, + "selection-done", + G_CALLBACK (&context_popup_selection_done), + ctx); + + gtk_menu_popup_at_pointer (menu, + event); + + return FALSE; +} + + +/** + * The user clicked the "add" button to add a new provider to the list. + * + * @param button the button object + * @param user_data the builder + */ void url_add_button_clicked_cb (GtkButton *button, gpointer user_data) @@ -52,12 +226,20 @@ url_add_button_clicked_cb (GtkButton *button, NULL, -1, AG_PMC_PROVIDER_URL, url, - -1); + AG_PMC_PROVIDER_STATUS, _("new"), + AG_PMC_PROVIDER_STATUS_COLOR, "yellow", + AG_PMC_PROVIDER_ENABLED, true, + AG_PMC_PROVIDER_SENSITIVE, false, + AG_PMC_PROVIDER_NOT_SENSITIVE, true, + -1); gtk_entry_set_text (entry, ""); } +/** + * FIXME. + */ void url_entry_changed_cb (GtkEntry *entry, gpointer user_data) @@ -117,14 +299,17 @@ edit_provider_dialog_response_cb (GtkDialog *dialog, &iter)) do { gchar *url; + gboolean enabled; gtk_tree_model_get (tm, &iter, AG_PMC_PROVIDER_URL, &url, + AG_PMC_PROVIDER_ENABLED, &enabled, -1); if (NULL == json_object_get (providers, url)) { + // FIXME: store enabled status in JSON state! GNUNET_assert (0 == json_array_append_new (urls, json_string (url))); @@ -185,10 +370,15 @@ anastasis_gtk_edit_provider_list_clicked_cb (GtkButton *object, { uint32_t http_code; uint32_t ec; + struct TALER_Amount ll; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_uint32 ("http_status", &http_code)), + // FIXME: check: right fieldname? + GNUNET_JSON_spec_mark_optional ( + TALER_JSON_spec_amount_any ("liability_limit", + &ll)), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_uint32 ("error_code", &ec)), @@ -196,7 +386,12 @@ anastasis_gtk_edit_provider_list_clicked_cb (GtkButton *object, }; char *status; const char *color; + bool sensitive = false; + const char *ll_s = NULL; + memset (&ll, + 0, + sizeof (ll)); if (GNUNET_OK != GNUNET_JSON_parse (provider, spec, @@ -212,6 +407,12 @@ anastasis_gtk_edit_provider_list_clicked_cb (GtkButton *object, { status = GNUNET_strdup (_ ("available")); color = "green"; + sensitive = true; + if (GNUNET_OK == + TALER_amount_is_valid (&ll)) + ll_s = TALER_amount2s (&ll); + else + GNUNET_break (0); } else if (0 == http_code) { @@ -231,13 +432,18 @@ anastasis_gtk_edit_provider_list_clicked_cb (GtkButton *object, (unsigned int) ec); color = "red"; } - gtk_list_store_insert_with_values (ls, - NULL, - -1, - AG_PMC_PROVIDER_URL, url, - AG_PMC_PROVIDER_STATUS, status, - AG_PMC_PROVIDER_STATUS_COLOR, color, - -1); + gtk_list_store_insert_with_values ( + ls, + NULL, + -1, + AG_PMC_PROVIDER_URL, url, + AG_PMC_PROVIDER_STATUS, status, + AG_PMC_PROVIDER_STATUS_COLOR, color, + AG_PMC_PROVIDER_LIABILITY_LIMIT, ll_s, + AG_PMC_PROVIDER_ENABLED, sensitive, // FIXME: store active/inactive status in JSON state! + AG_PMC_PROVIDER_SENSITIVE, sensitive, + AG_PMC_PROVIDER_NOT_SENSITIVE, ! sensitive, + -1); GNUNET_free (status); } } diff --git a/src/anastasis/anastasis-gtk_helper.h b/src/anastasis/anastasis-gtk_helper.h index f76f71f..91773df 100644 --- a/src/anastasis/anastasis-gtk_helper.h +++ b/src/anastasis/anastasis-gtk_helper.h @@ -1,6 +1,6 @@ /* This file is part of anastasis-gtk. - Copyright (C) 2020 Anastasis SARL + Copyright (C) 2020-2021 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 @@ -163,19 +163,40 @@ enum AG_ChallengeStatusModelColumns enum AG_ProviderModelColumns { /** - * A gchararray. + * A gchararray. Contains the providers base URL. */ AG_PMC_PROVIDER_URL = 0, /** - * A gchararray. + * A gchararray. Status of the provider in text. */ AG_PMC_PROVIDER_STATUS = 1, /** - * A gchararray. + * A gchararray. Color to use when rendering the status. + */ + AG_PMC_PROVIDER_STATUS_COLOR = 2, + + /** + * A gchararray. Amount as human-readable string with the provider's liability limit, + */ + AG_PMC_PROVIDER_LIABILITY_LIMIT = 3, + + /** + * A gboolean. true if this provider is enabled. */ - AG_PMC_PROVIDER_STATUS_COLOR = 2 + AG_PMC_PROVIDER_ENABLED = 4, + + /** + * A gboolean. true if this provider can be enabled. + */ + AG_PMC_PROVIDER_SENSITIVE = 5, + + /** + * A gboolean. false if this provider can be enabled. + */ + AG_PMC_PROVIDER_NOT_SENSITIVE = 6 + }; @@ -185,7 +206,7 @@ enum AG_ProviderModelColumns enum AG_BackupProviderColumns { /** - * A gchararray. + * A gchararray. */ AG_BPC_PROVIDER_URL = 0, |