gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-anastasis-gtk] branch master updated: work on policy editor


From: gnunet
Subject: [taler-anastasis-gtk] branch master updated: work on policy editor
Date: Sun, 04 Jul 2021 19:39:00 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository anastasis-gtk.

The following commit(s) were added to refs/heads/master by this push:
     new 35d1f5e  work on policy editor
35d1f5e is described below

commit 35d1f5ec167016490e09accaa61511c1617986f8
Author: Christian Grothoff <grothoff@gnunet.org>
AuthorDate: Sun Jul 4 19:38:58 2021 +0200

    work on policy editor
---
 contrib/anastasis_gtk_edit_policy.glade      |  32 +-
 src/anastasis/anastasis-gtk_pe-add-policy.c  |   4 +-
 src/anastasis/anastasis-gtk_pe-edit-policy.c | 420 ++++++++++++++++++++++++++-
 3 files changed, 421 insertions(+), 35 deletions(-)

diff --git a/contrib/anastasis_gtk_edit_policy.glade 
b/contrib/anastasis_gtk_edit_policy.glade
index 74668bf..b74c605 100644
--- a/contrib/anastasis_gtk_edit_policy.glade
+++ b/contrib/anastasis_gtk_edit_policy.glade
@@ -36,6 +36,7 @@
               <object class="GtkButton" id="ok_button">
                 <property name="label">gtk-ok</property>
                 <property name="visible">True</property>
+                <property name="sensitive">False</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
                 <property name="use_stock">True</property>
@@ -73,39 +74,14 @@
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
                         <property name="hexpand">True</property>
-                        <property name="row_spacing">5</property>
+                        <property name="row_spacing">10</property>
                         <property name="column_spacing">5</property>
                         <property name="row_homogeneous">True</property>
                         <child>
-                          <object class="GtkLabel" id="entry_label">
-                            <property name="visible">True</property>
-                            <property name="can_focus">False</property>
-                            <property name="margin_start">5</property>
-                            <property name="margin_end">5</property>
-                            <property name="margin_top">5</property>
-                            <property name="margin_bottom">5</property>
-                            <property name="label" 
translatable="yes">label</property>
-                          </object>
-                          <packing>
-                            <property name="left_attach">0</property>
-                            <property name="top_attach">0</property>
-                          </packing>
+                          <placeholder/>
                         </child>
                         <child>
-                          <object class="GtkComboBox" id="entry_combo_box">
-                            <property name="visible">True</property>
-                            <property name="can_focus">False</property>
-                            <property name="margin_start">5</property>
-                            <property name="margin_end">5</property>
-                            <property name="margin_top">5</property>
-                            <property name="margin_bottom">5</property>
-                            <property name="id_column">0</property>
-                            <signal name="changed" 
handler="anastasis_gtk_editor_entry_combo_box_changed_cb" swapped="no"/>
-                          </object>
-                          <packing>
-                            <property name="left_attach">1</property>
-                            <property name="top_attach">0</property>
-                          </packing>
+                          <placeholder/>
                         </child>
                       </object>
                     </child>
diff --git a/src/anastasis/anastasis-gtk_pe-add-policy.c 
b/src/anastasis/anastasis-gtk_pe-add-policy.c
index 911d0db..dfb19f4 100644
--- a/src/anastasis/anastasis-gtk_pe-add-policy.c
+++ b/src/anastasis/anastasis-gtk_pe-add-policy.c
@@ -33,7 +33,7 @@
 
 
 void
-AG_add_policy ()
+AG_add_policy (void)
 {
-  GNUNET_break (0);
+  AG_edit_policy (UINT_MAX);
 }
diff --git a/src/anastasis/anastasis-gtk_pe-edit-policy.c 
b/src/anastasis/anastasis-gtk_pe-edit-policy.c
index a71a95a..b24f194 100644
--- a/src/anastasis/anastasis-gtk_pe-edit-policy.c
+++ b/src/anastasis/anastasis-gtk_pe-edit-policy.c
@@ -31,27 +31,437 @@
 #include <jansson.h>
 
 
+/**
+ * Context for the edit dialog.
+ */
+struct EditDialogContext;
+
+/**
+ * Information we track per line in the grid.
+ */
+struct LineContext
+{
+  /**
+   * Kept in a DLL.
+   */
+  struct LineContext *next;
+
+  /**
+   * Kept in a DLL.
+   */
+  struct LineContext *prev;
+  
+  /**
+   * Context this line context belongs with.
+   */
+  struct EditDialogContext *edc;
+
+  /**
+   * Our combo box.
+   */
+  GtkComboBox *cb;
+  
+  /**
+   * Model for our combo box.
+   */
+  GtkTreeModel *model;
+  
+  /**
+   * Challenge index for this line. 
+   */
+  unsigned int cindex;
+  
+  /**
+   * Is this challenge used?
+   */
+  bool on;
+};
+
+
+/**
+ * Context for the edit dialog.
+ */
+struct EditDialogContext
+{
+  /**
+   * Builder of the dialog.
+   */
+  GtkBuilder *builder;
+
+  /**
+   * Head of line contexts for this dialog
+   */
+  struct LineContext *lc_head;
+
+  /**
+   * Tail of line contexts for this dialog
+   */
+  struct LineContext *lc_tail;
+
+  /**
+   * Policy index. UINT_MAX for a new policy.
+   */
+  unsigned int pindex;
+
+};
+
+
+/**
+ * Handle the response from the edit dialog. 
+ *
+ * @param dialog the dialog
+ * @param response_id what the user's action was
+ * @param user_data a `struct EditDialogContext`
+ */
 void
 anastasis_gtk_policy_edit_dialog_response_cb (
   GtkDialog *dialog,
   gint response_id,
   gpointer user_data)
 {
-  GNUNET_break (0);
+  struct EditDialogContext *edc = user_data;
+
+  if (GTK_RESPONSE_OK == response_id)
+  {
+    // FIXME: extract selected challenges and update/create policy!
+    GNUNET_break (0);
+  }
+
+  {
+    struct LineContext *lctx;
+
+    while (NULL != (lctx =edc->lc_head))
+    {
+      GNUNET_CONTAINER_DLL_remove (edc->lc_head,
+                                  edc->lc_tail,
+                                  lctx);
+      GNUNET_free (lctx);
+    }
+  }
+  gtk_widget_destroy (GTK_WIDGET (dialog));
+  g_object_unref (G_OBJECT (edc->builder));
+  GNUNET_free (edc);
 }
 
 
-void
-anastasis_gtk_editor_entry_combo_box_changed_cb (
+/**
+ * The user changed an entry in the combo boxy of an edit
+ * dialog. Update the ability to confirm the selection:
+ * if at least one authentication method is selected, the
+ * OK button should be sensitive.
+ *
+ * @param widget the combo box that was changed
+ * @param user_data the `struct EditDialogContext`
+ */
+static void
+combo_box_changed_cb (
   GtkComboBox *widget,
   gpointer user_data)
 {
-  GNUNET_break (0);
+  struct EditDialogContext *edc = user_data;
+
+  /* Update our line context's on/off flag */
+  for (struct LineContext *lctx = edc->lc_head;
+       NULL != lctx;
+       lctx = lctx->next)
+  {
+    GtkTreeIter iter;
+    gchar *url;
+    
+    if (lctx->cb != widget)
+      continue;
+    if (! gtk_combo_box_get_active_iter (lctx->cb,
+                                        &iter))
+    {
+      GNUNET_break (0);
+      continue;
+    }
+    gtk_tree_model_get (lctx->model,
+                       &iter,
+                       0, &url,
+                       -1);
+    lctx->on = (0 !=
+               strcmp (_("<off>"),
+                       url));
+    g_free (url);
+    break;
+  }
+  /* finally, update "OK" button sensitivity */
+  {
+    GtkWidget *ok_button;
+    bool legal = false;
+
+    for (struct LineContext *lctx = edc->lc_head;
+        NULL != lctx;
+        lctx = lctx->next)
+      legal |= lctx->on;
+    ok_button = GTK_WIDGET (gtk_builder_get_object (edc->builder,
+                                                   "ok_button"));
+    gtk_widget_set_sensitive (ok_button,
+                             legal);
+  }
+}
+
+
+/**
+ * Check if the authentication provider @a ap offers
+ * authentications of type @a type. If so, return true.
+ *
+ * @param type method to check for
+ * @param ap provider to check against
+ * @return true if @a ap offers @a type
+ */ 
+static bool
+ap_matches (const char *type,
+           json_t *ap)
+{
+  json_t *methods;
+  size_t index;
+  json_t *method;
+
+  methods = json_object_get (ap,
+                            "methods");
+  json_array_foreach (methods, index, method)
+  {
+    const char *offer;
+
+    offer = json_string_value (json_object_get (method,
+                                               "type"));
+    if (NULL == offer)
+    {
+      GNUNET_break (0);
+      continue;
+    }
+    if (0 == strcasecmp (type,
+                        offer))
+      return true;
+  }
+  return false;
+}
+
+
+/**
+ * Create a GtkListStore containing all of the URLs
+ * of Anastasis providers offering @a type as an 
+ * authentication method.
+ *
+ * @return the model
+ */
+static GtkTreeModel *
+make_model (const char *type)
+{
+  GtkListStore *ls;
+  json_t *aps;
+  const char *url;
+  json_t *ap;
+
+  ls = gtk_list_store_new (1,
+                          G_TYPE_STRING);
+  gtk_list_store_insert_with_values (ls,
+                                    NULL,
+                                    -1,
+                                    0, _("<off>"),
+                                    -1);
+  aps = json_object_get (AG_redux_state,
+                        "authentication_providers");
+  json_object_foreach (aps, url, ap) {
+    if (ap_matches (type,
+                   ap))
+      gtk_list_store_insert_with_values (ls,
+                                        NULL,
+                                        -1,
+                                        0, url,
+                                        -1);
+  }                  
+
+  return GTK_TREE_MODEL (ls);
+}
+
+
+/**
+ * Select entry in @a cb based on the @a url.
+ *
+ * @param url provider to select
+ * @param lctx line to update
+ */
+static void
+select_by_url (const char *url,
+              struct LineContext *lctx)
+{
+  GtkTreeIter iter;
+
+  if (! gtk_tree_model_get_iter_first (lctx->model,
+                                      &iter))
+  {
+    GNUNET_break (0);
+    return;
+  }
+  do {
+    gchar *have;
+
+    gtk_tree_model_get (lctx->model,
+                       &iter,
+                       0, &have,
+                       -1);
+    if (0 == strcmp (have,
+                    url))
+    {
+      gtk_combo_box_set_active_iter (lctx->cb,
+                                    &iter);
+      g_free (have);
+      return;
+    }
+    g_free (have);
+  } while (gtk_tree_model_iter_next (lctx->model,
+                                    &iter));
+  GNUNET_break (0); /* not found */
+}
+
+
+/**
+ * Select entry in @a cb based on the @a methods for
+ * challenge @a cindex.
+ *
+ * @param methods methods of policy to base selection on
+ * @param lctx line to update
+ */
+static void
+select_by_policy (const json_t *methods,
+                 struct LineContext *lctx)
+{
+  size_t index;
+  json_t *method;
+
+  json_array_foreach (methods, index, method) {
+    json_int_t am = json_integer_value (json_object_get (method,\
+                                                        
"authentication_method"));
+    const char *url;
+    
+    if (am != lctx->cindex)
+      continue;
+    url = json_string_value (json_object_get (method,
+                                             "provider"));
+    select_by_url (url,
+                  lctx);
+    break;
+  }
 }
 
 
 void
 AG_edit_policy (guint pindex)
 {
-  GNUNET_break (0);
+  struct EditDialogContext *edc;
+  GtkGrid *grid;
+  json_t *methods = NULL;
+  
+  edc = GNUNET_new (struct EditDialogContext);
+  edc->builder = GNUNET_GTK_get_new_builder ("anastasis_gtk_edit_policy.glade",
+                                            edc);
+  edc->pindex = pindex;
+  if (NULL == edc->builder)
+  {
+    GNUNET_break (0);
+    GNUNET_free (edc);
+    return;
+  }
+  if (UINT_MAX != pindex)
+  {
+    json_t *policies;
+    json_t *policy;
+
+    policies = json_object_get (AG_redux_state,
+                               "policies");
+    policy = json_array_get (policies,
+                            pindex);
+    methods = json_object_get (policy,
+                              "methods");
+    GNUNET_break (NULL != methods);
+  }
+  grid = GTK_GRID (gtk_builder_get_object (edc->builder,
+                                          "policy_grid"));
+  {
+    json_t *ams = json_object_get (AG_redux_state,
+                                 "authentication_methods");
+    json_t *am;
+    size_t index;
+    gint row = 0;
+
+    json_array_foreach (ams, index, am) {
+      const char *type;
+      const char *instructions;
+      struct GNUNET_JSON_Specification spec[] = {
+        GNUNET_JSON_spec_string ("type",
+                                &type),
+       GNUNET_JSON_spec_string ("instructions",
+                                &instructions),
+       GNUNET_JSON_spec_end ()
+      };
+      char *labels;
+      GtkWidget *label;
+      GtkWidget *cb;
+      struct LineContext *lctx;
+
+      if (GNUNET_OK !=
+         GNUNET_JSON_parse (am,
+                            spec,
+                            NULL, NULL))
+      {
+       GNUNET_break (0);
+       continue;
+      }
+      lctx = GNUNET_new (struct LineContext);
+      lctx->cindex = index;
+      GNUNET_asprintf (&labels,
+                      "<b>%s</b>: %s",
+                      type,
+                      instructions);
+      label = gtk_label_new (NULL);
+      gtk_label_set_markup (GTK_LABEL (label),
+                           labels);
+      GNUNET_free (labels);
+      lctx->model = make_model (type);
+      cb = gtk_combo_box_new_with_model (lctx->model);
+      lctx->cb = GTK_COMBO_BOX (cb);
+      lctx->edc = edc;
+      GNUNET_CONTAINER_DLL_insert (edc->lc_head,
+                                  edc->lc_tail,
+                                  lctx);
+      g_object_connect (cb,
+                       "signal::changed",
+                       &combo_box_changed_cb, lctx,
+                       NULL);
+      if (NULL != methods)
+       select_by_policy (methods,
+                         lctx);
+      gtk_grid_insert_row (grid,
+                          row);
+      gtk_grid_attach (grid,
+                      label,
+                      0,
+                      row,
+                      1,
+                      1);
+      gtk_grid_attach (grid,
+                      cb,
+                      1,
+                      row,
+                      1,
+                      1);
+      row++;
+    }
+  }
+  {
+    GtkWidget *toplevel;
+    GtkWidget *ad;
+    GtkWidget *anchor;
+
+    anchor = GTK_WIDGET (GCG_get_main_window_object 
("anastasis_gtk_main_window_quit_button"));
+    toplevel = gtk_widget_get_toplevel (anchor);
+    ad = GTK_WIDGET (gtk_builder_get_object (edc->builder,
+                                            
"anastasis_gtk_policy_edit_dialog"));
+    gtk_window_set_transient_for (GTK_WINDOW (ad),
+                                  GTK_WINDOW (toplevel));
+    gtk_window_present (GTK_WINDOW (ad));
+  }
 }

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]