[gnome-control-center/wip/add-account: 4/7] Populate the domain drop down with enterprise domains
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center/wip/add-account: 4/7] Populate the domain drop down with enterprise domains
- Date: Wed, 6 Jun 2012 12:09:51 +0000 (UTC)
commit f0b44a9a8d9181dd67521d38a7613c63148a5a10
Author: Stef Walter <stefw gnome org>
Date: Thu May 31 17:06:42 2012 +0200
Populate the domain drop down with enterprise domains
* Initial interaction with realmd
panels/user-accounts/Makefile.am | 15 ++-
panels/user-accounts/data/Makefile.am | 1 +
panels/user-accounts/data/account-dialog.ui | 5 +-
.../user-accounts/data/org.freedesktop.realmd.xml | 126 ++++++++++++++
panels/user-accounts/um-account-dialog.c | 181 +++++++++++++++++++-
5 files changed, 316 insertions(+), 12 deletions(-)
---
diff --git a/panels/user-accounts/Makefile.am b/panels/user-accounts/Makefile.am
index f23d8d8..d98b5fb 100644
--- a/panels/user-accounts/Makefile.am
+++ b/panels/user-accounts/Makefile.am
@@ -25,6 +25,10 @@ if BUILD_CHEESE
AM_CPPFLAGS += $(CHEESE_CFLAGS)
endif
+BUILT_SOURCES = \
+ um-realm-generated.c \
+ um-realm-generated.h
+
libuser_accounts_la_SOURCES = \
um-account-type.h \
um-account-type.c \
@@ -55,7 +59,8 @@ libuser_accounts_la_SOURCES = \
um-editable-combo.c \
um-user-panel.h \
um-user-panel.c \
- um-user-module.c
+ um-user-module.c \
+ $(BUILT_SOURCES)
libuser_accounts_la_LIBADD = \
$(PANEL_LIBS) \
@@ -71,6 +76,11 @@ endif
libuser_accounts_la_LDFLAGS = $(PANEL_LDFLAGS)
+um-realm-generated.c: $(srcdir)/data/org.freedesktop.realmd.xml
+ $(AM_V_GEN) gdbus-codegen --interface-prefix org.freedesktop.realmd. \
+ --generate-c-code um-realm-generated --c-namespace UmRealm $<
+um-realm-generated.h: um-realm-generated.c
+
frob_account_dialog_SOURCES = \
frob-account-dialog.c \
um-account-dialog.h \
@@ -80,7 +90,8 @@ frob_account_dialog_SOURCES = \
um-user-manager.h \
um-user-manager.c \
um-utils.h \
- um-utils.c
+ um-utils.c \
+ $(BUILT_SOURCES)
frob_account_dialog_LDADD = \
$(libuser_accounts_la_LIBADD)
diff --git a/panels/user-accounts/data/Makefile.am b/panels/user-accounts/data/Makefile.am
index dbc17c6..d03d14b 100644
--- a/panels/user-accounts/data/Makefile.am
+++ b/panels/user-accounts/data/Makefile.am
@@ -16,6 +16,7 @@ desktop_DATA = $(Desktop_in_files:.desktop.in=.desktop)
EXTRA_DIST = \
gnome-user-accounts-panel.desktop.in.in \
+ org.freedesktop.realmd.xml \
$(ui_DATA)
CLEANFILES = \
diff --git a/panels/user-accounts/data/account-dialog.ui b/panels/user-accounts/data/account-dialog.ui
index 217ad81..78ab9eb 100644
--- a/panels/user-accounts/data/account-dialog.ui
+++ b/panels/user-accounts/data/account-dialog.ui
@@ -271,15 +271,14 @@
<property name="orientation">vertical</property>
<property name="spacing">3</property>
<child>
- <object class="GtkComboBoxText" id="enterprise-domain">
+ <object class="GtkComboBox" id="enterprise-domain">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="has_entry">True</property>
<property name="entry_text_column">0</property>
- <property name="id_column">1</property>
<child internal-child="entry">
- <object class="GtkEntry" id="enterprise-domain-entry">
+ <object class="GtkEntry" id="combobox-entry">
<property name="can_focus">True</property>
</object>
</child>
diff --git a/panels/user-accounts/data/org.freedesktop.realmd.xml b/panels/user-accounts/data/org.freedesktop.realmd.xml
new file mode 100644
index 0000000..d929d2c
--- /dev/null
+++ b/panels/user-accounts/data/org.freedesktop.realmd.xml
@@ -0,0 +1,126 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+
+<node name="/">
+ <!--
+ * Global interface implemented by realmd. Allows listing of providers
+ * and discovering which one is relevant for a given domain.
+ *
+ * This is implemented by individual providers, but is aggregated
+ * globally at the system bus name 'org.freedesktop.realmd' with the
+ * object path '/org/freedesktop/realmd'
+ -->
+ <interface name="org.freedesktop.realmd.Provider">
+
+ <!--
+ * A list of known, enrolled or discovered realms.
+ * Each realm is a DBus object and is represeted by a:
+ * s: DBus bus name of the realm
+ * o: DBus object path of the realm
+ * s: DBus interface name, like 'ofr.KerberosRealm' (below)
+ -->
+ <property name="Realms" type="a(sos)" access="read"/>
+
+ <!--
+ * Discover whether a string represents a realm that a provider
+ * can enroll or otherwise use.
+ -->
+ <method name="Discover">
+ <!-- The input string -->
+ <arg name="string" type="s" direction="in"/>
+
+ <!-- Returned match relevance -->
+ <arg name="relevance" type="i" direction="out"/>
+
+ <!-- The realm objects: bus name, object path, interface -->
+ <arg name="realm" type="a(sos)" direction="out"/>
+ </method>
+ </interface>
+
+ <!--
+ * This interface is implemented by Providers and Realms to provide
+ * additional information when an long running operation is happening
+ *
+ * In particular you can connect to the "Diagnostics" signal when
+ * during an enroll or unenroll to get details.
+ -->
+ <interface name="org.freedesktop.realmd.Diagnostics">
+ <signal name="Diagnostics">
+ <arg name="data" type="s"/>
+ </signal>
+ </interface>
+
+ <!--
+ * This interface is implemented by Kerberos realms.
+ -->
+ <interface name="org.freedesktop.realmd.KerberosRealm">
+
+ <!--
+ * The kerberos realm name. Usually capitalized.
+ -->
+ <property name="Name" type="s" access="read"/>
+
+ <!--
+ * The DNS domain name for this realm.
+ -->
+ <property name="Domain" type="s" access="read"/>
+
+ <!--
+ * The format for user logins when this realm is enrolled.
+ * This property may not be valid unless machine is enrolled
+ * in this realm. The format contains a %s where the user name
+ * goes eg: "DOMAIN\%s"
+ -->
+ <property name="UserFormat" type="s" access="read"/>
+
+ <!--
+ * Whether the machine is enrolled in this realm or not.
+ -->
+ <property name="Enrolled" type="b" access="read"/>
+
+ <!--
+ * Enroll the machine in this realm using an administrative
+ * account and a password.
+ -->
+ <method name="EnrollWithPassword">
+ <arg name="principal" type="s" direction="in"/>
+ <arg name="password" type="s" direction="in"/>
+ <arg name="options" type="a{sv}" direction="in"/>
+ </method>
+
+ <!--
+ * Enroll the machine in this realm using kerberos cached
+ * administrative credentials.
+ -->
+ <method name="EnrollWithCredentialCache">
+ <!-- The contents of a kerberos cache file containing administrative credentials -->
+ <arg name="kerberos_cache" type="ay" direction="in">
+ <annotation name="org.gtk.GDBus.C.ForceGVariant" value="yup"/>
+ </arg>
+ <arg name="options" type="a{sv}" direction="in"/>
+ </method>
+
+ <!--
+ * Unenroll the machine from this realm using an administrative
+ * account and a password.
+ -->
+ <method name="UnenrollWithPassword">
+ <arg name="principal" type="s" direction="in"/>
+ <arg name="password" type="s" direction="in"/>
+ <arg name="options" type="a{sv}" direction="in"/>
+ </method>
+
+ <!--
+ * Unenroll the machine from this realm using a kerberos cached
+ * administrative credentials.
+ -->
+ <method name="UnenrollWithCredentialCache">
+ <!-- The contents of a kerberos cache file containing administrative credentials -->
+ <arg name="kerberos_cache" type="ay" direction="in">
+ <annotation name="org.gtk.GDBus.C.ForceGVariant" value="yup"/>
+ </arg>
+ <arg name="options" type="a{sv}" direction="in"/>
+ </method>
+
+ </interface>
+</node>
diff --git a/panels/user-accounts/um-account-dialog.c b/panels/user-accounts/um-account-dialog.c
index 518b8cb..7574c10 100644
--- a/panels/user-accounts/um-account-dialog.c
+++ b/panels/user-accounts/um-account-dialog.c
@@ -27,6 +27,7 @@
#include <gtk/gtk.h>
#include "um-account-dialog.h"
+#include "um-realm-generated.h"
#include "um-user-manager.h"
#include "um-utils.h"
@@ -45,6 +46,8 @@ struct _UmAccountDialog {
GtkDialog parent;
GtkNotebook *notebook;
GSimpleAsyncResult *async;
+ GCancellable *cancellable;
+
GtkWidget *bar;
gboolean bar_updating;
@@ -54,9 +57,13 @@ struct _UmAccountDialog {
GtkWidget *local_account_type;
/* Enterprise users */
- GtkWidget *enterprise_domain;
+ guint realmd_watch;
+ GtkWidget *enterprise_button;
+ GtkListStore *enterprise_realms;
+ GtkComboBox *enterprise_domain;
GtkWidget *enterprise_login;
GtkWidget *enterprise_password;
+ UmRealmProvider *realm_provider;
};
typedef struct {
@@ -392,14 +399,158 @@ enterprise_add (UmAccountDialog *self)
}
static void
+on_realm_proxy_created (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ UmAccountDialog *self = UM_ACCOUNT_DIALOG (user_data);
+ UmRealmKerberosRealm *realm;
+ GError *error = NULL;
+ GtkTreeIter iter;
+
+ realm = um_realm_kerberos_realm_proxy_new_finish (result, &error);
+
+ if (error != NULL) {
+ g_warning ("Couldn't create realm proxy: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ gtk_list_store_append (self->enterprise_realms, &iter);
+ gtk_list_store_set (self->enterprise_realms, &iter,
+ 0, um_realm_kerberos_realm_get_domain (realm),
+ 1, realm,
+ -1);
+
+ if (um_realm_kerberos_realm_get_enrolled (realm))
+ gtk_combo_box_set_active_iter (self->enterprise_domain, &iter);
+
+ g_object_unref (realm);
+}
+
+static void
+enterprise_populate_realms (UmAccountDialog *self,
+ GDBusConnection *connection,
+ GVariant *realms)
+{
+ GVariantIter iter;
+ const gchar *path;
+ const gchar *name;
+ const gchar *iface;
+
+ if (realms == NULL)
+ return;
+
+ /* We only support kerberos realms */
+
+ g_variant_iter_init (&iter, realms);
+ while (g_variant_iter_loop (&iter, "(&s&o&s)", &name, &path, &iface)) {
+ if (g_str_equal (iface, "org.freedesktop.realmd.KerberosRealm")) {
+ um_realm_kerberos_realm_proxy_new (connection, G_DBUS_PROXY_FLAGS_NONE,
+ name, path, self->cancellable,
+ on_realm_proxy_created, self);
+ }
+ }
+}
+
+static void
+on_provider_discover_default (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ UmAccountDialog *self = UM_ACCOUNT_DIALOG (user_data);
+ GDBusConnection *connection;
+ GError *error = NULL;
+ GVariant *realms;
+ gint relevance;
+
+ um_realm_provider_call_discover_finish (self->realm_provider, &relevance,
+ &realms, result, &error);
+ if (error == NULL) {
+ connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (self->realm_provider));
+ enterprise_populate_realms (self, connection, realms);
+ g_variant_unref (realms);
+ } else {
+ g_warning ("Couldn't discover default realm: %s", error->message);
+ g_error_free (error);
+ }
+}
+
+static void
+on_provider_proxy_created (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ UmAccountDialog *self = UM_ACCOUNT_DIALOG (user_data);
+ GDBusConnection *connection;
+ GError *error = NULL;
+ GVariant *realms;
+
+ g_clear_object (&self->realm_provider);
+
+ self->realm_provider = um_realm_provider_proxy_new_for_bus_finish (result, &error);
+ if (error != NULL) {
+ if (!g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN))
+ g_warning ("Couldn't contact realmd service: %s", error->message);
+ g_error_free (error);
+ }
+
+ if (!self->realm_provider)
+ return;
+
+ connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (self->realm_provider));
+
+ /* Lookup all the realm objects */
+ realms = um_realm_provider_get_realms (self->realm_provider);
+ enterprise_populate_realms (self, connection, realms);
+
+ /* When no realms try to discover a sensible default */
+ um_realm_provider_call_discover (self->realm_provider, "", self->cancellable,
+ on_provider_discover_default, self);
+
+ /* Show the 'Enterprise Login' stuff, and update bar */
+ gtk_widget_show (self->enterprise_button);
+ bar_update (self, NULL);
+}
+
+static void
+on_realmd_appeared (GDBusConnection *connection,
+ const gchar *name,
+ const gchar *name_owner,
+ gpointer user_data)
+{
+ UmAccountDialog *self = UM_ACCOUNT_DIALOG (user_data);
+ um_realm_provider_proxy_new (connection, G_DBUS_PROXY_FLAGS_NONE,
+ name, "/org/freedesktop/realmd",
+ self->cancellable, on_provider_proxy_created, self);
+}
+
+static void
+on_realmd_disappeared (GDBusConnection *connection,
+ const gchar *name,
+ gpointer user_data)
+{
+ UmAccountDialog *self = UM_ACCOUNT_DIALOG (user_data);
+ gtk_list_store_clear (self->enterprise_realms);
+ g_clear_object (&self->realm_provider);
+ gtk_widget_hide (self->enterprise_button);
+ bar_update (self, NULL);
+}
+
+static void
enterprise_construct (UmAccountDialog *self,
GtkBuilder *builder)
{
GtkWidget *widget;
+ self->enterprise_realms = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_OBJECT);
+
widget = (GtkWidget *) gtk_builder_get_object (builder, "enterprise-domain");
g_signal_connect (widget, "notify::text", G_CALLBACK (on_text_changed), self);
- self->enterprise_domain = widget;
+ self->enterprise_domain = GTK_COMBO_BOX (widget);
+ gtk_combo_box_set_model (self->enterprise_domain,
+ GTK_TREE_MODEL (self->enterprise_realms));
+ gtk_combo_box_set_entry_text_column (self->enterprise_domain, 0);
widget = (GtkWidget *) gtk_builder_get_object (builder, "enterprise-login");
g_signal_connect (widget, "notify::text", G_CALLBACK (on_text_changed), self);
@@ -408,15 +559,20 @@ enterprise_construct (UmAccountDialog *self,
widget = (GtkWidget *) gtk_builder_get_object (builder, "enterprise-password");
self->enterprise_password = widget;
- /* TODO: Populate the drop down for enrolled domains */
- /* TODO: Choose first domain if so */
- /* TODO: If another domain not selected, then validate and enter current domain name */
+ /* Initially we hide the 'Enterprise Login' stuff */
+ widget = (GtkWidget *) gtk_builder_get_object (builder, "enterprise-button");
+ self->enterprise_button = widget;
+ gtk_widget_hide (widget);
+
+ self->realmd_watch = g_bus_watch_name (G_BUS_TYPE_SYSTEM, "org.freedesktop.realmd",
+ G_BUS_NAME_WATCHER_FLAGS_AUTO_START,
+ on_realmd_appeared, on_realmd_disappeared,
+ self, NULL);
}
static void
enterprise_clear (UmAccountDialog *self)
{
- gtk_entry_set_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (self->enterprise_domain))), "");
gtk_entry_set_text (GTK_ENTRY (self->enterprise_login), "");
gtk_entry_set_text (GTK_ENTRY (self->enterprise_password), "");
}
@@ -424,7 +580,7 @@ enterprise_clear (UmAccountDialog *self)
static void
um_account_dialog_init (UmAccountDialog *self)
{
-
+ self->cancellable = g_cancellable_new ();
}
static void
@@ -503,12 +659,23 @@ um_account_dialog_response (GtkDialog *dialog,
break;
}
+ g_cancellable_cancel (self->cancellable);
gtk_widget_hide (GTK_WIDGET (self));
}
static void
um_account_dialog_finalize (GObject *obj)
{
+ UmAccountDialog *self = UM_ACCOUNT_DIALOG (obj);
+
+ g_cancellable_cancel (self->cancellable);
+ g_object_unref (self->cancellable);
+ g_object_unref (self->enterprise_realms);
+ g_clear_object (&self->realm_provider);
+
+ if (self->realmd_watch)
+ g_bus_unwatch_name (self->realmd_watch);
+
G_OBJECT_CLASS (um_account_dialog_parent_class)->finalize (obj);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]