[gnome-initial-setup: 13/20] account: Create two users if parental controls are enabled



commit d8d1af4210a97783b4e05c4c0531db671a5bda49
Author: Philip Withnall <withnall endlessm com>
Date:   Thu Feb 6 13:04:12 2020 +0000

    account: Create two users if parental controls are enabled
    
    Add a check button for enabling parental controls. If it’s ticked,
    create two users when saving data (one child, one parent), rather than
    one.
    
    Ensure the administrator account (the parent) is created first, in case
    we fail between creating the two accounts. We always need the system to
    have one administrator account otherwise recovery is impossible.
    
    Signed-off-by: Philip Withnall <withnall endlessm com>

 .../pages/account/gis-account-page-local.c         | 82 ++++++++++++++++++++--
 .../pages/account/gis-account-page-local.ui        | 34 +++++++++
 .../pages/account/gis-account-page.c               | 29 ++++++--
 3 files changed, 133 insertions(+), 12 deletions(-)
---
diff --git a/gnome-initial-setup/pages/account/gis-account-page-local.c 
b/gnome-initial-setup/pages/account/gis-account-page-local.c
index a017b85..a38cebf 100644
--- a/gnome-initial-setup/pages/account/gis-account-page-local.c
+++ b/gnome-initial-setup/pages/account/gis-account-page-local.c
@@ -50,6 +50,7 @@ struct _GisAccountPageLocalPrivate
   GtkWidget *header;
   GtkWidget *fullname_entry;
   GtkWidget *username_combo;
+  GtkWidget *enable_parental_controls_check_button;
   gboolean   has_custom_username;
   GtkWidget *username_explanation;
   UmPhotoDialog *photo_dialog;
@@ -73,7 +74,8 @@ G_DEFINE_TYPE_WITH_PRIVATE (GisAccountPageLocal, gis_account_page_local, GTK_TYP
 
 enum {
   VALIDATION_CHANGED,
-  USER_CREATED,
+  MAIN_USER_CREATED,
+  PARENT_USER_CREATED,
   CONFIRM,
   LAST_SIGNAL,
 };
@@ -389,6 +391,20 @@ confirm (GisAccountPageLocal *page)
     g_signal_emit (page, signals[CONFIRM], 0);
 }
 
+static void
+enable_parental_controls_check_button_toggled_cb (GtkToggleButton *toggle_button,
+                                                  gpointer         user_data)
+{
+  GisAccountPageLocal *page = GIS_ACCOUNT_PAGE_LOCAL (user_data);
+  GisAccountPageLocalPrivate *priv = gis_account_page_local_get_instance_private (page);
+  gboolean parental_controls_enabled = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON 
(priv->enable_parental_controls_check_button));
+
+  /* This sets the account type of the main user. When we save_data(), we create
+   * two users if parental controls are enabled: the first user is always an
+   * admin, and the second user is the main user using this @account_type. */
+  priv->account_type = parental_controls_enabled ? ACT_USER_ACCOUNT_TYPE_STANDARD : 
ACT_USER_ACCOUNT_TYPE_ADMINISTRATOR;
+}
+
 static void
 gis_account_page_local_constructed (GObject *object)
 {
@@ -414,6 +430,13 @@ gis_account_page_local_constructed (GObject *object)
                             "activate", G_CALLBACK (confirm), page);
   g_signal_connect_swapped (priv->fullname_entry, "activate",
                             G_CALLBACK (confirm), page);
+  g_signal_connect (priv->enable_parental_controls_check_button, "toggled",
+                    G_CALLBACK (enable_parental_controls_check_button_toggled_cb), page);
+
+  /* Disable parental controls if support is not compiled in. */
+#ifndef HAVE_PARENTAL_CONTROLS
+  gtk_widget_hide (priv->enable_parental_controls_check_button);
+#endif
 
   priv->valid_name = FALSE;
   priv->valid_username = FALSE;
@@ -516,11 +539,30 @@ local_create_user (GisAccountPageLocal *page)
   const gchar *username;
   const gchar *fullname;
   g_autoptr(GError) local_error = NULL;
+  gboolean parental_controls_enabled;
   g_autoptr(ActUser) main_user = NULL;
+  g_autoptr(ActUser) parent_user = NULL;
 
   username = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (priv->username_combo));
   fullname = gtk_entry_get_text (GTK_ENTRY (priv->fullname_entry));
+  parental_controls_enabled = gis_driver_get_parental_controls_enabled (GIS_PAGE (page)->driver);
+
+  /* Always create the admin user first, in case of failure part-way through
+   * this function, which would leave us with no admin user at all. */
+  if (parental_controls_enabled) {
+    const gchar *parent_username = "administrator";
+    const gchar *parent_fullname = _("Administrator");
+
+    parent_user = act_user_manager_create_user (priv->act_client, parent_username, parent_fullname, 
ACT_USER_ACCOUNT_TYPE_ADMINISTRATOR, &local_error);
+    if (local_error != NULL) {
+      g_warning ("Failed to create parent user: %s", local_error->message);
+      return;
+    }
+
+    g_signal_emit (page, signals[PARENT_USER_CREATED], 0, parent_user, "");
+  }
 
+  /* Now create the main user. */
   main_user = act_user_manager_create_user (priv->act_client, username, fullname, priv->account_type, 
&local_error);
   if (local_error != NULL) {
     g_warning ("Failed to create user: %s", local_error->message);
@@ -529,7 +571,7 @@ local_create_user (GisAccountPageLocal *page)
 
   set_user_avatar (page, main_user);
 
-  g_signal_emit (page, signals[USER_CREATED], 0, main_user, "");
+  g_signal_emit (page, signals[MAIN_USER_CREATED], 0, main_user, "");
 }
 
 static void
@@ -545,6 +587,7 @@ gis_account_page_local_class_init (GisAccountPageLocalClass *klass)
   gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisAccountPageLocal, 
fullname_entry);
   gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisAccountPageLocal, 
username_combo);
   gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisAccountPageLocal, 
username_explanation);
+  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisAccountPageLocal, 
enable_parental_controls_check_button);
 
   object_class->constructed = gis_account_page_local_constructed;
   object_class->dispose = gis_account_page_local_dispose;
@@ -553,9 +596,13 @@ gis_account_page_local_class_init (GisAccountPageLocalClass *klass)
                                               G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
                                               G_TYPE_NONE, 0);
 
-  signals[USER_CREATED] = g_signal_new ("user-created", GIS_TYPE_ACCOUNT_PAGE_LOCAL,
-                                        G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
-                                        G_TYPE_NONE, 2, ACT_TYPE_USER, G_TYPE_STRING);
+  signals[MAIN_USER_CREATED] = g_signal_new ("main-user-created", GIS_TYPE_ACCOUNT_PAGE_LOCAL,
+                                             G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
+                                             G_TYPE_NONE, 2, ACT_TYPE_USER, G_TYPE_STRING);
+
+  signals[PARENT_USER_CREATED] = g_signal_new ("parent-user-created", GIS_TYPE_ACCOUNT_PAGE_LOCAL,
+                                               G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
+                                               G_TYPE_NONE, 2, ACT_TYPE_USER, G_TYPE_STRING);
 
   signals[CONFIRM] = g_signal_new ("confirm", GIS_TYPE_ACCOUNT_PAGE_LOCAL,
                                    G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
@@ -587,11 +634,34 @@ gboolean
 gis_account_page_local_apply (GisAccountPageLocal *local, GisPage *page)
 {
   GisAccountPageLocalPrivate *priv = gis_account_page_local_get_instance_private (local);
-  const gchar *username;
+  const gchar *username, *full_name;
+  gboolean parental_controls_enabled;
 
   username = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (priv->username_combo));
   gis_driver_set_username (GIS_PAGE (page)->driver, username);
 
+  full_name = gtk_entry_get_text (GTK_ENTRY (priv->fullname_entry));
+  gis_driver_set_full_name (GIS_PAGE (page)->driver, full_name);
+
+  if (priv->avatar_pixbuf != NULL)
+    {
+      gis_driver_set_avatar (GIS_PAGE (page)->driver, priv->avatar_pixbuf);
+    }
+  else if (priv->avatar_filename != NULL)
+    {
+      g_autoptr(GdkPixbuf) pixbuf = NULL;
+
+      pixbuf = gdk_pixbuf_new_from_file_at_size (priv->avatar_filename, 96, 96, NULL);
+      gis_driver_set_avatar (GIS_PAGE (page)->driver, pixbuf);
+    }
+
+#ifdef HAVE_PARENTAL_CONTROLS
+  parental_controls_enabled = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON 
(priv->enable_parental_controls_check_button));
+#else
+  parental_controls_enabled = FALSE;
+#endif
+  gis_driver_set_parental_controls_enabled (GIS_PAGE (page)->driver, parental_controls_enabled);
+
   return FALSE;
 }
 
diff --git a/gnome-initial-setup/pages/account/gis-account-page-local.ui 
b/gnome-initial-setup/pages/account/gis-account-page-local.ui
index 520f80a..8a668a1 100644
--- a/gnome-initial-setup/pages/account/gis-account-page-local.ui
+++ b/gnome-initial-setup/pages/account/gis-account-page-local.ui
@@ -139,6 +139,40 @@
                 <property name="height">1</property>
               </packing>
             </child>
+            <child>
+              <object class="GtkBox">
+                <property name="visible">True</property>
+                <property name="orientation">vertical</property>
+                <child>
+                  <object class="GtkCheckButton" id="enable_parental_controls_check_button">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Set up _parental controls for this 
user</property>
+                    <property name="use-underline">True</property>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkLabel">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">For use by a parent or supervisor, who must 
set up their own password.</property>
+                    <property name="yalign">0</property>
+                    <property name="xalign">0</property>
+                    <property name="margin-left">24</property>
+                    <style>
+                      <class name="dim-label"/>
+                    </style>
+                    <attributes>
+                      <attribute name="scale" value="0.8"/>
+                    </attributes>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="top_attach">6</property>
+                <property name="width">1</property>
+                <property name="height">1</property>
+              </packing>
+            </child>
           </object>
         </child>
       </object>
diff --git a/gnome-initial-setup/pages/account/gis-account-page.c 
b/gnome-initial-setup/pages/account/gis-account-page.c
index 089ab97..1ba7107 100644
--- a/gnome-initial-setup/pages/account/gis-account-page.c
+++ b/gnome-initial-setup/pages/account/gis-account-page.c
@@ -169,10 +169,10 @@ gis_account_page_shown (GisPage *gis_page)
 }
 
 static void
-on_local_user_created (GtkWidget      *page_local,
-                       ActUser        *user,
-                       char           *password,
-                       GisAccountPage *page)
+on_local_main_user_created (GtkWidget      *page_local,
+                            ActUser        *user,
+                            const gchar    *password,
+                            GisAccountPage *page)
 {
   const gchar *language;
 
@@ -183,6 +183,21 @@ on_local_user_created (GtkWidget      *page_local,
   gis_driver_set_user_permissions (GIS_PAGE (page)->driver, user, password);
 }
 
+static void
+on_local_parent_user_created (GtkWidget      *page_local,
+                              ActUser        *user,
+                              const gchar    *password,
+                              GisAccountPage *page)
+{
+  const gchar *language;
+
+  language = gis_driver_get_user_language (GIS_PAGE (page)->driver);
+  if (language)
+    act_user_set_language (user, language);
+
+  gis_driver_set_parent_permissions (GIS_PAGE (page)->driver, user, password);
+}
+
 static void
 on_local_page_confirmed (GisAccountPageLocal *local,
                          GisAccountPage      *page)
@@ -230,8 +245,10 @@ gis_account_page_constructed (GObject *object)
 
   g_signal_connect (priv->page_local, "validation-changed",
                     G_CALLBACK (on_validation_changed), page);
-  g_signal_connect (priv->page_local, "user-created",
-                    G_CALLBACK (on_local_user_created), page);
+  g_signal_connect (priv->page_local, "main-user-created",
+                    G_CALLBACK (on_local_main_user_created), page);
+  g_signal_connect (priv->page_local, "parent-user-created",
+                    G_CALLBACK (on_local_parent_user_created), page);
   g_signal_connect (priv->page_local, "confirm",
                     G_CALLBACK (on_local_page_confirmed), page);
 


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