/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ /* * Copyright (C) 2012 Red Hat * * This program 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 2 of the * License, or (at your option) any later version. * * This program 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 this program; if not, see . * * Written by: * Jasper St. Pierre */ /* Summary page {{{1 */ #define PAGE_ID "summary" #include "config.h" #include "summary-resources.h" #include "gis-summary-page.h" #include #include #include #include #include #include #define SERVICE_NAME "gdm-password" struct _GisSummaryPagePrivate { GtkWidget *start_button; AdwStatusPage *status_page; ActUser *user_account; const gchar *user_password; }; typedef struct _GisSummaryPagePrivate GisSummaryPagePrivate; G_DEFINE_TYPE_WITH_PRIVATE (GisSummaryPage, gis_summary_page, GIS_TYPE_PAGE); static void request_info_query (GisSummaryPage *page, GdmUserVerifier *user_verifier, const char *question, gboolean is_secret) { /* TODO: pop up modal dialog */ g_debug ("user verifier asks%s question: %s", is_secret ? " secret" : "", question); } static void on_info (GdmUserVerifier *user_verifier, const char *service_name, const char *info, GisSummaryPage *page) { g_debug ("PAM module info: %s", info); } static void on_problem (GdmUserVerifier *user_verifier, const char *service_name, const char *problem, GisSummaryPage *page) { g_warning ("PAM module error: %s", problem); } static void on_info_query (GdmUserVerifier *user_verifier, const char *service_name, const char *question, GisSummaryPage *page) { request_info_query (page, user_verifier, question, FALSE); } static void on_secret_info_query (GdmUserVerifier *user_verifier, const char *service_name, const char *question, GisSummaryPage *page) { GisSummaryPagePrivate *priv = gis_summary_page_get_instance_private (page); gboolean should_send_password = priv->user_password != NULL; g_debug ("PAM module secret info query: %s", question); if (should_send_password) { g_debug ("sending password\n"); gdm_user_verifier_call_answer_query (user_verifier, service_name, priv->user_password, NULL, NULL, NULL); priv->user_password = NULL; } else { request_info_query (page, user_verifier, question, TRUE); } } static void on_session_opened (GdmGreeter *greeter, const char *service_name, GisSummaryPage *page) { gdm_greeter_call_start_session_when_ready_sync (greeter, service_name, TRUE, NULL, NULL); } static void add_uid_file (uid_t uid) { gchar *gis_uid_path; gchar *uid_str; g_autoptr(GError) error = NULL; gis_uid_path = g_build_filename (g_get_home_dir (), "gnome-initial-setup-uid", NULL); uid_str = g_strdup_printf ("%u", uid); if (!g_file_set_contents (gis_uid_path, uid_str, -1, &error)) g_warning ("Unable to create %s: %s", gis_uid_path, error->message); g_free (uid_str); g_free (gis_uid_path); } static void log_user_in (GisSummaryPage *page) { GisSummaryPagePrivate *priv = gis_summary_page_get_instance_private (page); g_autoptr(GError) error = NULL; GdmGreeter *greeter = NULL; GdmUserVerifier *user_verifier = NULL; if (!gis_driver_get_gdm_objects (GIS_PAGE (page)->driver, &greeter, &user_verifier)) { g_warning ("No GDM connection; not initiating login"); return; } g_signal_connect (user_verifier, "info", G_CALLBACK (on_info), page); g_signal_connect (user_verifier, "problem", G_CALLBACK (on_problem), page); g_signal_connect (user_verifier, "info-query", G_CALLBACK (on_info_query), page); g_signal_connect (user_verifier, "secret-info-query", G_CALLBACK (on_secret_info_query), page); g_signal_connect (greeter, "session-opened", G_CALLBACK (on_session_opened), page); /* We are in NEW_USER mode and we want to make it possible for third * parties to find out which user ID we created. */ add_uid_file (act_user_get_uid (priv->user_account)); gdm_user_verifier_call_begin_verification_for_user_sync (user_verifier, SERVICE_NAME, act_user_get_user_name (priv->user_account), NULL, &error); if (error != NULL) g_warning ("Could not begin verification: %s", error->message); } static void done_cb (GtkButton *button, GisSummaryPage *page) { gis_ensure_stamp_files (GIS_PAGE (page)->driver); switch (gis_driver_get_mode (GIS_PAGE (page)->driver)) { case GIS_DRIVER_MODE_NEW_USER: gis_driver_hide_window (GIS_PAGE (page)->driver); log_user_in (page); break; case GIS_DRIVER_MODE_EXISTING_USER: g_application_quit (G_APPLICATION (GIS_PAGE (page)->driver)); default: break; } } static void gis_summary_page_shown (GisPage *page) { GisSummaryPage *summary = GIS_SUMMARY_PAGE (page); GisSummaryPagePrivate *priv = gis_summary_page_get_instance_private (summary); g_autoptr(GError) local_error = NULL; if (!gis_driver_save_data (GIS_PAGE (page)->driver, &local_error)) { /* FIXME: This should probably be shown to the user and some options * provided to them. */ g_warning ("Error saving data: %s", local_error->message); } gis_driver_get_user_permissions (GIS_PAGE (page)->driver, &priv->user_account, &priv->user_password); gtk_widget_grab_focus (priv->start_button); } static void update_distro_name (GisSummaryPage *page) { GisSummaryPagePrivate *priv = gis_summary_page_get_instance_private (page); g_autofree char *name = g_get_os_info (G_OS_INFO_KEY_NAME); char *text; if (!name) name = g_strdup ("GNOME"); /* Translators: the parameter here is the name of a distribution, * like "Fedora" or "Ubuntu". It falls back to "GNOME" if we can't * detect any distribution. */ text = g_strdup_printf (_("_Start Using %s"), name); gtk_button_set_label (GTK_BUTTON (priv->start_button), text); g_free (text); /* Translators: the parameter here is the name of a distribution, * like "Fedora" or "Ubuntu". It falls back to "GNOME" if we can't * detect any distribution. */ text = g_strdup_printf (_("%s is ready to be used. We hope that you love it!"), name); adw_status_page_set_description (priv->status_page, text); g_free (text); } static void gis_summary_page_constructed (GObject *object) { GisSummaryPage *page = GIS_SUMMARY_PAGE (object); GisSummaryPagePrivate *priv = gis_summary_page_get_instance_private (page); G_OBJECT_CLASS (gis_summary_page_parent_class)->constructed (object); update_distro_name (page); g_signal_connect (priv->start_button, "clicked", G_CALLBACK (done_cb), page); gis_page_set_complete (GIS_PAGE (page), TRUE); gtk_widget_show (GTK_WIDGET (page)); } static void gis_summary_page_locale_changed (GisPage *page) { gis_page_set_title (page, _("Setup Complete")); update_distro_name (GIS_SUMMARY_PAGE (page)); } static void gis_summary_page_class_init (GisSummaryPageClass *klass) { GisPageClass *page_class = GIS_PAGE_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass); gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass), "/org/gnome/initial-setup/gis-summary-page.ui"); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisSummaryPage, start_button); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisSummaryPage, status_page); page_class->page_id = PAGE_ID; page_class->locale_changed = gis_summary_page_locale_changed; page_class->shown = gis_summary_page_shown; object_class->constructed = gis_summary_page_constructed; } static void gis_summary_page_init (GisSummaryPage *page) { g_resources_register (summary_get_resource ()); gtk_widget_init_template (GTK_WIDGET (page)); } GisPage * gis_prepare_summary_page (GisDriver *driver) { return g_object_new (GIS_TYPE_SUMMARY_PAGE, "driver", driver, NULL); }