chiark / gitweb /
Switch Disobedience reset (i.e. fresh login) notification over to
[disorder] / disobedience / users.c
index 80f3bf2fbd0b30419428c6f6bcb122757eff2f58..0590d699b67157aa69d90d03c9614d167c64ccbf 100644 (file)
@@ -109,10 +109,16 @@ static int users_find_user(const char *user,
  *
  * If users_deferred_select is set then that user is selected.
  */
-static void users_got_list(void attribute((unused)) *v, int nvec, char **vec) {
+static void users_got_list(void attribute((unused)) *v,
+                           const char *error,
+                           int nvec, char **vec) {
   int n;
   GtkTreeIter iter;
 
+  if(error) {
+    popup_protocol_error(0, error);
+    return;
+  }
   /* Present users in alphabetical order */
   qsort(vec, nvec, sizeof (char *), usercmp);
   /* Set the list contents */
@@ -248,26 +254,26 @@ static void users_add_right_group(const char *title,
                                   rights_type mask) {
   const uint32_t first = mask / 7;
   const int bit = leftmost_bit(first);
-  GtkWidget **widgets = &users_details_rights[bit], *any, *mine, *random;
+  GtkWidget **widgets = &users_details_rights[bit], *any, *mine, *rnd;
 
   if(!*widgets) {
     GtkWidget *hbox = gtk_hbox_new(FALSE, 2);
 
     any = widgets[0] = gtk_check_button_new_with_label("Any");
     mine = widgets[1] = gtk_check_button_new_with_label("Own");
-    random = widgets[2] = gtk_check_button_new_with_label("Random");
+    rnd = widgets[2] = gtk_check_button_new_with_label("Random");
     gtk_box_pack_start(GTK_BOX(hbox), any, FALSE, FALSE, 0);
     gtk_box_pack_start(GTK_BOX(hbox), mine, FALSE, FALSE, 0);
-    gtk_box_pack_start(GTK_BOX(hbox), random, FALSE, FALSE, 0);
+    gtk_box_pack_start(GTK_BOX(hbox), rnd, FALSE, FALSE, 0);
     users_detail_generic(title, hbox);
     g_signal_connect(any, "toggled", G_CALLBACK(users_any_toggled), NULL);
     users_details_rights[bit] = any;
     users_details_rights[bit + 1] = mine;
-    users_details_rights[bit + 2] = random;
+    users_details_rights[bit + 2] = rnd;
   } else {
     any = widgets[0];
     mine = widgets[1];
-    random = widgets[2];
+    rnd = widgets[2];
   }
   /* Discard irrelevant bits */
   bits &= mask;
@@ -275,7 +281,7 @@ static void users_add_right_group(const char *title,
   bits >>= bit;
   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(any), !!(bits & 1));
   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mine), !!(bits & 2));
-  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(random), !!(bits & 4));
+  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rnd), !!(bits & 4));
 }
 
 /** @brief Called when the details table is destroyed */
@@ -380,42 +386,38 @@ static rights_type users_get_rights(void) {
   return r;
 }
 
-/** @brief Called when various things fail */
-static void users_op_failed(struct callbackdata attribute((unused)) *cbd,
-                            int attribute((unused)) code,
-                            const char *msg) {
-  popup_submsg(users_window, GTK_MESSAGE_ERROR, msg);
+/** @brief Called when a user setting has been edited */
+static void users_edituser_completed(void attribute((unused)) *v,
+                                     const char *error) {
+  if(error)
+    popup_submsg(users_window, GTK_MESSAGE_ERROR, error);
 }
 
 /** @brief Called when a new user has been created */
-static void users_adduser_completed(void *v) {
-  struct callbackdata *cbd = v;
-
-  /* Now the user is created we can go ahead and set the email address */
-  if(*cbd->u.edituser.email) {
-    struct callbackdata *ncbd = xmalloc(sizeof *cbd);
-    ncbd->onerror = users_op_failed;
-    disorder_eclient_edituser(client, NULL, cbd->u.edituser.user,
-                              "email", cbd->u.edituser.email, ncbd);
+static void users_adduser_completed(void *v,
+                                    const char *error) {
+  if(error) {
+    popup_submsg(users_window, GTK_MESSAGE_ERROR, error);
+    mode(ADD);                          /* Let the user try again */
+  } else {
+    const struct kvp *const kvp = v;
+    const char *user = kvp_get(kvp, "user");
+    const char *email = kvp_get(kvp, "email"); /* maybe NULL */
+
+    /* Now the user is created we can go ahead and set the email address */
+    if(email)
+      disorder_eclient_edituser(client, users_edituser_completed, user,
+                                "email", email, NULL);
+    /* Refresh the list of users */
+    disorder_eclient_users(client, users_got_list, 0);
+    /* We'll select the newly created user */
+    users_deferred_select = user;
   }
-  /* Refresh the list of users */
-  disorder_eclient_users(client, users_got_list, 0);
-  /* We'll select the newly created user */
-  users_deferred_select = cbd->u.edituser.user;
-}
-
-/** @brief Called if creating a new user fails */
-static void users_adduser_failed(struct callbackdata attribute((unused)) *cbd,
-                                 int attribute((unused)) code,
-                                 const char *msg) {
-  popup_submsg(users_window, GTK_MESSAGE_ERROR, msg);
-  mode(ADD);                            /* Let the user try again */
 }
 
 /** @brief Called when the 'Apply' button is pressed */
 static void users_apply(GtkButton attribute((unused)) *button,
                         gpointer attribute((unused)) userdata) {
-  struct callbackdata *cbd;
   const char *password;
   const char *password2;
   const char *name;
@@ -447,15 +449,14 @@ static void users_apply(GtkButton attribute((unused)) *button,
       popup_submsg(users_window, GTK_MESSAGE_ERROR, "Invalid email address");
       return;
     }
-    cbd = xmalloc(sizeof *cbd);
-    cbd->onerror = users_adduser_failed;
-    cbd->u.edituser.user = name;
-    cbd->u.edituser.email = email;
-    disorder_eclient_adduser(client, users_adduser_completed,
+    disorder_eclient_adduser(client,
+                             users_adduser_completed,
                              name,
                              password,
                              rights_string(users_get_rights()),
-                             cbd);
+                             kvp_make("user", name,
+                                      "email", email,
+                                      (char *)0));
     /* We switch to no-op mode while creating the user */
     mode(NONE);
     break;
@@ -472,26 +473,30 @@ static void users_apply(GtkButton attribute((unused)) *button,
       popup_submsg(users_window, GTK_MESSAGE_ERROR, "Invalid email address");
       return;
     }
-    cbd = xmalloc(sizeof *cbd);
-    cbd->onerror = users_op_failed;
-    disorder_eclient_edituser(client, NULL, users_selected,
-                              "email", email, cbd);
-    disorder_eclient_edituser(client, NULL, users_selected,
-                              "password", password, cbd);
-    disorder_eclient_edituser(client, NULL, users_selected,
-                              "rights", rights_string(users_get_rights()), cbd);
+    disorder_eclient_edituser(client, users_edituser_completed, users_selected,
+                              "email", email, NULL);
+    disorder_eclient_edituser(client, users_edituser_completed, users_selected,
+                              "password", password, NULL);
+    disorder_eclient_edituser(client, users_edituser_completed, users_selected,
+                              "rights", rights_string(users_get_rights()), NULL);
     /* We remain in edit mode */
     break;
   }
 }
 
 /** @brief Called when a user has been deleted */
-static void users_deleted(void *v) {
-  const struct callbackdata *const cbd = v;
-  GtkTreeIter iter[1];
-
-  if(!users_find_user(cbd->u.user, iter))    /* Find the user... */
-    gtk_list_store_remove(users_list, iter); /* ...and remove them */
+static void users_delete_completed(void *v,
+                                   const char *error) {
+  if(error)
+    popup_submsg(users_window, GTK_MESSAGE_ERROR, error);
+  else {
+    const struct kvp *const kvp = v;
+    const char *const user = kvp_get(kvp, "user");
+    GtkTreeIter iter[1];
+    
+    if(!users_find_user(user, iter))           /* Find the user... */
+      gtk_list_store_remove(users_list, iter); /* ...and remove them */
+  }
 }
 
 /** @brief Called when the 'Delete' button is pressed */
@@ -499,7 +504,6 @@ static void users_delete(GtkButton attribute((unused)) *button,
                         gpointer attribute((unused)) userdata) {
   GtkWidget *yesno;
   int res;
-  struct callbackdata *cbd;
 
   if(!users_selected)
     return;
@@ -513,22 +517,35 @@ static void users_delete(GtkButton attribute((unused)) *button,
   res = gtk_dialog_run(GTK_DIALOG(yesno));
   gtk_widget_destroy(yesno);
   if(res == GTK_RESPONSE_YES) {
-    cbd = xmalloc(sizeof *cbd);
-    cbd->onerror = users_op_failed;
-    cbd->u.user = users_selected;
-    disorder_eclient_deluser(client, users_deleted, cbd->u.user, cbd);
+    disorder_eclient_deluser(client, users_delete_completed, users_selected,
+                             kvp_make("user", users_selected,
+                                      (char *)0));
   }
 }
 
-static void users_got_email(void attribute((unused)) *v, const char *value) {
+static void users_got_email(void attribute((unused)) *v,
+                            const char *error,
+                            const char *value) {
+  if(error)
+    popup_protocol_error(0, error);
   users_email = value;
 }
 
-static void users_got_rights(void attribute((unused)) *v, const char *value) {
+static void users_got_rights(void attribute((unused)) *v,
+                             const char *error,
+                             const char *value) {
+  if(error)
+    popup_protocol_error(0, error);
   users_rights = value;
 }
 
-static void users_got_password(void attribute((unused)) *v, const char *value) {
+static void users_got_password(void attribute((unused)) *v,
+                               const char *error,
+                               const char *value) {
+  if(error)
+    popup_protocol_error(0, error);
+  /* TODO if an error occurred gathering user info, we should react in some
+   * different way */
   users_password = value;
   users_makedetails(users_selected,
                     users_email,