From 4bc98095413d20f95ef54d58d2d36ca83e65b8a9 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Nov 03 2016 06:13:48 +0000 Subject: import gnome-online-accounts-3.14.5-5.el7 --- diff --git a/.gitignore b/.gitignore index 17cfdaf..ea6c0cf 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/gnome-online-accounts-3.14.4.tar.xz +SOURCES/gnome-online-accounts-3.14.5.tar.xz diff --git a/.gnome-online-accounts.metadata b/.gnome-online-accounts.metadata index 0356ca8..fa15f22 100644 --- a/.gnome-online-accounts.metadata +++ b/.gnome-online-accounts.metadata @@ -1 +1 @@ -1e1364c4ff1446f64fff164153e75f995be1fb22 SOURCES/gnome-online-accounts-3.14.4.tar.xz +ab1bbe163535184cdb80a236f48d04b537977aef SOURCES/gnome-online-accounts-3.14.5.tar.xz diff --git a/SOURCES/0001-daemon-Don-t-leak-the-GoaProvider.patch b/SOURCES/0001-daemon-Don-t-leak-the-GoaProvider.patch deleted file mode 100644 index dc6f1bc..0000000 --- a/SOURCES/0001-daemon-Don-t-leak-the-GoaProvider.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 5e06329c3668da308055e5cd4b75730b45389124 Mon Sep 17 00:00:00 2001 -From: Debarshi Ray -Date: Wed, 27 May 2015 19:01:44 +0200 -Subject: [PATCH] daemon: Don't leak the GoaProvider - -https://bugzilla.gnome.org/show_bug.cgi?id=693578 ---- - src/daemon/goadaemon.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/src/daemon/goadaemon.c b/src/daemon/goadaemon.c -index 9d5543d..56292b1 100644 ---- a/src/daemon/goadaemon.c -+++ b/src/daemon/goadaemon.c -@@ -1158,7 +1158,7 @@ on_account_handle_ensure_credentials (GoaAccount *account, - gpointer user_data) - { - GoaDaemon *daemon = GOA_DAEMON (user_data); -- GoaProvider *provider; -+ GoaProvider *provider = NULL; - GoaObject *object; - - object = GOA_OBJECT (g_dbus_interface_get_object (G_DBUS_INTERFACE (account))); -@@ -1181,5 +1181,6 @@ on_account_handle_ensure_credentials (GoaAccount *account, - ensure_data_new (daemon, object, invocation)); - - out: -+ g_clear_object (&provider); - return TRUE; /* invocation was handled */ - } --- -2.1.0 - diff --git a/SOURCES/ensure-credentials-startup-and-network-change.patch b/SOURCES/ensure-credentials-startup-and-network-change.patch index 27d6ad0..9e34d67 100644 --- a/SOURCES/ensure-credentials-startup-and-network-change.patch +++ b/SOURCES/ensure-credentials-startup-and-network-change.patch @@ -1,4 +1,4 @@ -From b1d87d540c2229dc9954efe73feebcaf5aad41eb Mon Sep 17 00:00:00 2001 +From 3353374f93a16412444bb4fea5384f1a9ea9156f Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Wed, 27 May 2015 15:15:09 +0200 Subject: [PATCH 01/12] daemon: Style fixes @@ -9,7 +9,7 @@ Use the name 'self' to refer to the instance. 1 file changed, 69 insertions(+), 69 deletions(-) diff --git a/src/daemon/goadaemon.c b/src/daemon/goadaemon.c -index 89cbed8..55a576d 100644 +index 1aa0f18aee45..f4aa0c2f95d9 100644 --- a/src/daemon/goadaemon.c +++ b/src/daemon/goadaemon.c @@ -1,6 +1,6 @@ @@ -239,7 +239,7 @@ index 89cbed8..55a576d 100644 for (l = existing_objects; l != NULL; l = l->next) { GoaObject *object = GOA_OBJECT (l->data); -@@ -579,13 +579,13 @@ process_config_entries (GoaDaemon *daemon, +@@ -579,14 +579,14 @@ process_config_entries (GoaDaemon *daemon, { const gchar *object_path = l->data; GoaObject *object; @@ -249,13 +249,14 @@ index 89cbed8..55a576d 100644 g_signal_handlers_disconnect_by_func (goa_object_peek_account (object), G_CALLBACK (on_account_handle_remove), daemon); + g_object_unref (object); g_debug ("removing %s", object_path); - g_warn_if_fail (g_dbus_object_manager_server_unexport (daemon->object_manager, object_path)); + g_warn_if_fail (g_dbus_object_manager_server_unexport (self->object_manager, object_path)); } for (l = added; l != NULL; l = l->next) { -@@ -600,22 +600,22 @@ process_config_entries (GoaDaemon *daemon, +@@ -601,22 +601,22 @@ process_config_entries (GoaDaemon *daemon, g_warn_if_fail (key_file_data != NULL); object = goa_object_skeleton_new (object_path); @@ -282,7 +283,7 @@ index 89cbed8..55a576d 100644 } g_object_unref (object); g_free (group); -@@ -632,9 +632,9 @@ process_config_entries (GoaDaemon *daemon, +@@ -633,9 +633,9 @@ process_config_entries (GoaDaemon *daemon, key_file_data = g_hash_table_lookup (group_name_to_key_file_data, group); g_warn_if_fail (key_file_data != NULL); @@ -294,7 +295,7 @@ index 89cbed8..55a576d 100644 GOA_OBJECT_SKELETON (object), key_file_data->path, group, -@@ -643,11 +643,11 @@ process_config_entries (GoaDaemon *daemon, +@@ -644,11 +644,11 @@ process_config_entries (GoaDaemon *daemon, { g_signal_handlers_disconnect_by_func (goa_object_peek_account (object), G_CALLBACK (on_account_handle_remove), @@ -309,7 +310,7 @@ index 89cbed8..55a576d 100644 } g_object_unref (object); g_free (group); -@@ -664,14 +664,14 @@ process_config_entries (GoaDaemon *daemon, +@@ -665,14 +665,14 @@ process_config_entries (GoaDaemon *daemon, /* * goa_daemon_reload_configuration: @@ -326,7 +327,7 @@ index 89cbed8..55a576d 100644 { GList *key_files_to_free; GHashTable *group_name_to_key_file_data; -@@ -685,11 +685,11 @@ goa_daemon_reload_configuration (GoaDaemon *daemon) +@@ -686,11 +686,11 @@ goa_daemon_reload_configuration (GoaDaemon *daemon) /* Read the main user config file at $HOME/.config/goa-1.0/accounts.conf */ path = g_strdup_printf ("%s/goa-1.0/accounts.conf", g_get_user_config_dir ()); @@ -340,7 +341,7 @@ index 89cbed8..55a576d 100644 g_hash_table_unref (group_name_to_key_file_data); g_list_foreach (key_files_to_free, (GFunc) g_key_file_free, NULL); -@@ -697,7 +697,7 @@ goa_daemon_reload_configuration (GoaDaemon *daemon) +@@ -698,7 +698,7 @@ goa_daemon_reload_configuration (GoaDaemon *daemon) } static gchar * @@ -349,7 +350,7 @@ index 89cbed8..55a576d 100644 { static guint counter = 0; GDateTime *dt; -@@ -915,11 +915,11 @@ on_manager_handle_add_account (GoaManager *manager, +@@ -916,11 +916,11 @@ on_manager_handle_add_account (GoaManager *manager, GVariant *details, gpointer user_data) { @@ -363,7 +364,7 @@ index 89cbed8..55a576d 100644 data->manager = g_object_ref (manager); data->invocation = g_object_ref (invocation); data->provider_type = g_strdup (provider_type); -@@ -940,7 +940,7 @@ on_account_handle_remove (GoaAccount *account, +@@ -941,7 +941,7 @@ on_account_handle_remove (GoaAccount *account, GDBusMethodInvocation *invocation, gpointer user_data) { @@ -372,7 +373,7 @@ index 89cbed8..55a576d 100644 GoaProvider *provider; GKeyFile *key_file; const gchar *provider_type; -@@ -1037,7 +1037,7 @@ on_account_handle_remove (GoaAccount *account, +@@ -1038,7 +1038,7 @@ on_account_handle_remove (GoaAccount *account, goto out; } @@ -381,7 +382,7 @@ index 89cbed8..55a576d 100644 goa_account_complete_remove (account, invocation); -@@ -1062,13 +1062,13 @@ typedef struct +@@ -1063,13 +1063,13 @@ typedef struct } EnsureData; static EnsureData * @@ -397,7 +398,7 @@ index 89cbed8..55a576d 100644 data->object = g_object_ref (object); data->invocation = invocation; return data; -@@ -1156,7 +1156,7 @@ on_account_handle_ensure_credentials (GoaAccount *account, +@@ -1157,7 +1157,7 @@ on_account_handle_ensure_credentials (GoaAccount *account, GDBusMethodInvocation *invocation, gpointer user_data) { @@ -406,7 +407,7 @@ index 89cbed8..55a576d 100644 GoaProvider *provider = NULL; GoaObject *object; -@@ -1177,7 +1177,7 @@ on_account_handle_ensure_credentials (GoaAccount *account, +@@ -1178,7 +1178,7 @@ on_account_handle_ensure_credentials (GoaAccount *account, object, NULL, /* GCancellable */ (GAsyncReadyCallback) ensure_credentials_cb, @@ -416,10 +417,10 @@ index 89cbed8..55a576d 100644 out: g_clear_object (&provider); -- -2.1.0 +2.5.0 -From dec43aa3281420cc8bbb51e70b0db27886d0080a Mon Sep 17 00:00:00 2001 +From d649ab10c5a75504aab75d88f873ce8f78c4a0a9 Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Wed, 27 May 2015 17:17:42 +0200 Subject: [PATCH 02/12] daemon: Use G_SOURCE_REMOVE instead of FALSE @@ -429,7 +430,7 @@ Subject: [PATCH 02/12] daemon: Use G_SOURCE_REMOVE instead of FALSE 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/daemon/goadaemon.c b/src/daemon/goadaemon.c -index 55a576d..a7b2967 100644 +index f4aa0c2f95d9..253ef7b68760 100644 --- a/src/daemon/goadaemon.c +++ b/src/daemon/goadaemon.c @@ -144,7 +144,7 @@ on_config_file_monitor_timeout (gpointer user_data) @@ -442,10 +443,10 @@ index 55a576d..a7b2967 100644 static void -- -2.1.0 +2.5.0 -From 1e6a783a779efab7524b981c0c164bfa393577ae Mon Sep 17 00:00:00 2001 +From c53298a8e9af407fb220b317acbb61e55d047f75 Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Wed, 27 May 2015 19:07:39 +0200 Subject: [PATCH 03/12] daemon: Use g_clear_object wherever applicable @@ -456,7 +457,7 @@ https://bugzilla.gnome.org/show_bug.cgi?id=693578 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/daemon/goadaemon.c b/src/daemon/goadaemon.c -index a7b2967..e6a559d 100644 +index 253ef7b68760..978a9e781a52 100644 --- a/src/daemon/goadaemon.c +++ b/src/daemon/goadaemon.c @@ -445,6 +445,8 @@ update_account_object (GoaDaemon *self, @@ -484,7 +485,7 @@ index a7b2967..e6a559d 100644 g_free (type); g_free (identity); g_free (presentation_identity); -@@ -1042,8 +1042,7 @@ on_account_handle_remove (GoaAccount *account, +@@ -1043,8 +1043,7 @@ on_account_handle_remove (GoaAccount *account, goa_account_complete_remove (account, invocation); out: @@ -495,10 +496,10 @@ index a7b2967..e6a559d 100644 if (key_file != NULL) g_key_file_free (key_file); -- -2.1.0 +2.5.0 -From 6f91a7a8c3106d4c3e7c11e819e07316cd3aa4c8 Mon Sep 17 00:00:00 2001 +From 4cae5ecbdfb934719ff278d9ae3fda07ef61658d Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Wed, 27 May 2015 19:11:54 +0200 Subject: [PATCH 04/12] daemon: Use g_list_free_full wherever applicable @@ -509,7 +510,7 @@ https://bugzilla.gnome.org/show_bug.cgi?id=693578 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/daemon/goadaemon.c b/src/daemon/goadaemon.c -index e6a559d..79d6f26 100644 +index 978a9e781a52..b0105593106c 100644 --- a/src/daemon/goadaemon.c +++ b/src/daemon/goadaemon.c @@ -544,8 +544,7 @@ process_config_entries (GoaDaemon *self, @@ -522,7 +523,7 @@ index e6a559d..79d6f26 100644 } config_object_paths = NULL; -@@ -656,10 +655,8 @@ process_config_entries (GoaDaemon *self, +@@ -657,10 +656,8 @@ process_config_entries (GoaDaemon *self, g_list_free (removed); g_list_free (added); g_list_free (unchanged); @@ -535,7 +536,7 @@ index e6a559d..79d6f26 100644 } /* -@@ -692,8 +689,7 @@ goa_daemon_reload_configuration (GoaDaemon *self) +@@ -693,8 +690,7 @@ goa_daemon_reload_configuration (GoaDaemon *self) process_config_entries (self, group_name_to_key_file_data); g_hash_table_unref (group_name_to_key_file_data); @@ -546,10 +547,10 @@ index e6a559d..79d6f26 100644 static gchar * -- -2.1.0 +2.5.0 -From df7b534a62e49be6b32360e01ea19f542b5ea548 Mon Sep 17 00:00:00 2001 +From 14df59620e57965b81f448f1e6a707c3e319c7b2 Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Wed, 27 May 2015 19:13:18 +0200 Subject: [PATCH 05/12] daemon: Remove redundant NULL check @@ -560,10 +561,10 @@ https://bugzilla.gnome.org/show_bug.cgi?id=693578 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/daemon/goadaemon.c b/src/daemon/goadaemon.c -index 79d6f26..eeb49e6 100644 +index b0105593106c..01b85e43634a 100644 --- a/src/daemon/goadaemon.c +++ b/src/daemon/goadaemon.c -@@ -881,8 +881,7 @@ get_all_providers_cb (GObject *source, +@@ -882,8 +882,7 @@ get_all_providers_cb (GObject *source, out: g_free (object_path); @@ -574,10 +575,10 @@ index 79d6f26..eeb49e6 100644 g_free (group); g_free (id); -- -2.1.0 +2.5.0 -From e1568184f6e6a18b0a10ff94f18729fd29892edb Mon Sep 17 00:00:00 2001 +From ab4de26b7613b60594ea8044f46f798e7b6f18cb Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Thu, 28 May 2015 13:26:06 +0200 Subject: [PATCH 06/12] daemon: Remove redundant function call @@ -588,10 +589,10 @@ https://bugzilla.gnome.org/show_bug.cgi?id=693578 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/daemon/goadaemon.c b/src/daemon/goadaemon.c -index eeb49e6..f933e69 100644 +index 01b85e43634a..03d329c2c127 100644 --- a/src/daemon/goadaemon.c +++ b/src/daemon/goadaemon.c -@@ -1138,9 +1138,7 @@ ensure_credentials_cb (GoaProvider *provider, +@@ -1139,9 +1139,7 @@ ensure_credentials_cb (GoaProvider *provider, g_message ("%s: Setting AttentionNeeded to FALSE because EnsureCredentials() succeded\n", g_dbus_object_get_object_path (G_DBUS_OBJECT (data->object))); } @@ -603,10 +604,10 @@ index eeb49e6..f933e69 100644 ensure_data_unref (data); } -- -2.1.0 +2.5.0 -From b8d56056ecb1ddb62c21a9eae90daf97d275b8bf Mon Sep 17 00:00:00 2001 +From b1d8f19f0c794e26cb2cb9b26993d7874d90afba Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Thu, 28 May 2015 15:51:23 +0200 Subject: [PATCH 07/12] daemon: Check & refresh credentials during startup and @@ -618,7 +619,7 @@ https://bugzilla.gnome.org/show_bug.cgi?id=693578 1 file changed, 101 insertions(+), 2 deletions(-) diff --git a/src/daemon/goadaemon.c b/src/daemon/goadaemon.c -index f933e69..efa7ba7 100644 +index 03d329c2c127..1a7b1fff65b5 100644 --- a/src/daemon/goadaemon.c +++ b/src/daemon/goadaemon.c @@ -36,11 +36,14 @@ struct _GoaDaemon @@ -711,7 +712,7 @@ index f933e69..efa7ba7 100644 #ifdef GOA_KERBEROS_ENABLED activate_identity_service (self); #endif -@@ -1123,7 +1170,14 @@ ensure_credentials_cb (GoaProvider *provider, +@@ -1124,7 +1171,14 @@ ensure_credentials_cb (GoaProvider *provider, error->message, g_quark_to_string (error->domain), error->code); } } @@ -727,7 +728,7 @@ index f933e69..efa7ba7 100644 } else { -@@ -1138,7 +1192,9 @@ ensure_credentials_cb (GoaProvider *provider, +@@ -1139,7 +1193,9 @@ ensure_credentials_cb (GoaProvider *provider, g_message ("%s: Setting AttentionNeeded to FALSE because EnsureCredentials() succeded\n", g_dbus_object_get_object_path (G_DBUS_OBJECT (data->object))); } @@ -738,7 +739,7 @@ index f933e69..efa7ba7 100644 } ensure_data_unref (data); } -@@ -1175,3 +1231,46 @@ on_account_handle_ensure_credentials (GoaAccount *account, +@@ -1176,3 +1232,46 @@ on_account_handle_ensure_credentials (GoaAccount *account, g_clear_object (&provider); return TRUE; /* invocation was handled */ } @@ -786,10 +787,10 @@ index f933e69..efa7ba7 100644 + g_list_free_full (objects, g_object_unref); +} -- -2.1.0 +2.5.0 -From f261c93bfddfc96f261a7388d1c46524d408d4e6 Mon Sep 17 00:00:00 2001 +From f2c57a95ed7beb5e9ee0303ae4fbc7ff47e822e4 Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Thu, 28 May 2015 16:20:57 +0200 Subject: [PATCH 08/12] kerberos: Mark EnsureCredentials failures as @@ -806,7 +807,7 @@ https://bugzilla.gnome.org/show_bug.cgi?id=693578 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/goabackend/goakerberosprovider.c b/src/goabackend/goakerberosprovider.c -index 2eb6b67..33dc1ad 100644 +index 2eb6b677ab22..33dc1ad096fa 100644 --- a/src/goabackend/goakerberosprovider.c +++ b/src/goabackend/goakerberosprovider.c @@ -1406,18 +1406,29 @@ ensure_credentials_sync (GoaProvider *provider, @@ -842,10 +843,10 @@ index 2eb6b67..33dc1ad 100644 if (identity == NULL) identity = get_identity_from_object_manager (GOA_KERBEROS_PROVIDER (provider), -- -2.1.0 +2.5.0 -From 77f5b03632b779499e29b2e91c55a562c362cfc9 Mon Sep 17 00:00:00 2001 +From 2a4765eed5b804aee25bfd7a924e72f202751f2d Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Fri, 29 May 2015 15:40:32 +0200 Subject: [PATCH 09/12] client, identity: Use g_list_free_full wherever @@ -858,7 +859,7 @@ https://bugzilla.gnome.org/show_bug.cgi?id=693578 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/goa/goaclient.c b/src/goa/goaclient.c -index 89d52c8..20d6e88 100644 +index 89d52c84f711..20d6e8813fd8 100644 --- a/src/goa/goaclient.c +++ b/src/goa/goaclient.c @@ -471,8 +471,7 @@ goa_client_get_accounts (GoaClient *client) @@ -872,7 +873,7 @@ index 89d52c8..20d6e88 100644 return ret; } diff --git a/src/goaidentity/goakerberosidentitymanager.c b/src/goaidentity/goakerberosidentitymanager.c -index a1898c9..162cf3f 100644 +index a1898c99d703..162cf3f54fcf 100644 --- a/src/goaidentity/goakerberosidentitymanager.c +++ b/src/goaidentity/goakerberosidentitymanager.c @@ -594,8 +594,7 @@ identity_sort_func (GoaIdentity *a, @@ -886,10 +887,10 @@ index a1898c9..162cf3f 100644 static void -- -2.1.0 +2.5.0 -From 3939e2be726b532dba0debfc3d4b933ae8d54e1a Mon Sep 17 00:00:00 2001 +From 56752aaf92f7c474b023d88b1000d89cf857f2d1 Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Fri, 29 May 2015 15:45:10 +0200 Subject: [PATCH 10/12] identity: Simplify the destruction @@ -904,7 +905,7 @@ https://bugzilla.gnome.org/show_bug.cgi?id=693578 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/goaidentity/goakerberosidentityinquiry.c b/src/goaidentity/goakerberosidentityinquiry.c -index 7c9a84a..4560b35 100644 +index 7c9a84a1a733..4560b358b149 100644 --- a/src/goaidentity/goakerberosidentityinquiry.c +++ b/src/goaidentity/goakerberosidentityinquiry.c @@ -102,15 +102,15 @@ goa_kerberos_identity_inquiry_dispose (GObject *object) @@ -928,10 +929,10 @@ index 7c9a84a..4560b35 100644 } -- -2.1.0 +2.5.0 -From b7340b085604b291f4f894fe747ab109c19edc03 Mon Sep 17 00:00:00 2001 +From ffc90f63bea5331206cdf4f62c5f799975df9bab Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Fri, 29 May 2015 15:46:09 +0200 Subject: [PATCH 11/12] identity: Chain up during dispose @@ -942,7 +943,7 @@ https://bugzilla.gnome.org/show_bug.cgi?id=693578 1 file changed, 2 insertions(+) diff --git a/src/goaidentity/goakerberosidentityinquiry.c b/src/goaidentity/goakerberosidentityinquiry.c -index 4560b35..67a8a60 100644 +index 4560b358b149..67a8a6000a15 100644 --- a/src/goaidentity/goakerberosidentityinquiry.c +++ b/src/goaidentity/goakerberosidentityinquiry.c @@ -102,6 +102,8 @@ goa_kerberos_identity_inquiry_dispose (GObject *object) @@ -955,10 +956,10 @@ index 4560b35..67a8a60 100644 static void -- -2.1.0 +2.5.0 -From 59061d81175411c2b38c4d87dfd94b0f3893b765 Mon Sep 17 00:00:00 2001 +From 6898eb14f14a7498f484af251f4e0826e7afe521 Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Fri, 29 May 2015 17:51:33 +0200 Subject: [PATCH 12/12] kerberos: Don't leak the GCancellable @@ -968,7 +969,7 @@ Subject: [PATCH 12/12] kerberos: Don't leak the GCancellable 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/goabackend/goakerberosprovider.c b/src/goabackend/goakerberosprovider.c -index 33dc1ad..69a1c91 100644 +index 33dc1ad096fa..69a1c9142466 100644 --- a/src/goabackend/goakerberosprovider.c +++ b/src/goabackend/goakerberosprovider.c @@ -990,9 +990,10 @@ perform_initial_sign_in (GoaKerberosProvider *self, @@ -995,5 +996,5 @@ index 33dc1ad..69a1c91 100644 static char * -- -2.1.0 +2.5.0 diff --git a/SOURCES/kerberos-fail-early-on-ticket-request-when-ticketing.patch b/SOURCES/kerberos-fail-early-on-ticket-request-when-ticketing.patch new file mode 100644 index 0000000..fda5c34 --- /dev/null +++ b/SOURCES/kerberos-fail-early-on-ticket-request-when-ticketing.patch @@ -0,0 +1,45 @@ +From 9731022ab1e229efb48b32b29fa96885f95f2391 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Tue, 13 Oct 2015 09:05:30 -0400 +Subject: [PATCH] kerberos: Fail early on ticket request when ticketing + disabled + +Right now, it's possible to crash gnome-online-account if you +turn of the kerberos slider at just the right moment when it's +doing a refresh. + +This is because it will try to get a ticket when ticketing has +already been disabled (and the ticketing interface is unset). + +This commit adds a check for that. + +https://bugzilla.gnome.org/show_bug.cgi?id=756498 +--- + src/goabackend/goakerberosprovider.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/src/goabackend/goakerberosprovider.c b/src/goabackend/goakerberosprovider.c +index f51f56a0a34a..32e9ab257ae6 100644 +--- a/src/goabackend/goakerberosprovider.c ++++ b/src/goabackend/goakerberosprovider.c +@@ -300,7 +300,16 @@ get_ticket_sync (GoaKerberosProvider *self, + account = goa_object_peek_account (object); + identifier = goa_account_get_identity (account); + +- ticketing = goa_object_get_ticketing (GOA_OBJECT (object)); ++ ticketing = goa_object_get_ticketing (object); ++ if (ticketing == NULL) ++ { ++ g_set_error (error, ++ GOA_ERROR, ++ GOA_ERROR_NOT_SUPPORTED, ++ _("Ticketing is disabled for account")); ++ return FALSE; ++ } ++ + details = goa_ticketing_get_details (ticketing); + + preauth_source = NULL; +-- +2.5.5 + diff --git a/SOURCES/kerberos-fix-renewal.patch b/SOURCES/kerberos-fix-renewal.patch index 8465fa5..1f47244 100644 --- a/SOURCES/kerberos-fix-renewal.patch +++ b/SOURCES/kerberos-fix-renewal.patch @@ -1,7 +1,7 @@ -From 3d9361b917ef923f39ba54835512171d83e457b7 Mon Sep 17 00:00:00 2001 +From 25a3cc4de532748e162ad84451407e3263f8d512 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Tue, 22 Sep 2015 14:33:35 -0400 -Subject: [PATCH 1/3] identity: consider ticket start time when calculating +Subject: [PATCH 1/2] identity: consider ticket start time when calculating renewal time Right now we try to renew the kerberos ticket at the midpoint between @@ -24,37 +24,10 @@ and expiration time of the ticket. 2 files changed, 53 insertions(+), 9 deletions(-) diff --git a/src/goaidentity/goaidentity.c b/src/goaidentity/goaidentity.c -index 2fc491b..2904e2a 100644 +index 2fc491be2876..2904e2afe020 100644 --- a/src/goaidentity/goaidentity.c +++ b/src/goaidentity/goaidentity.c -@@ -13,60 +13,67 @@ - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General - * Public License along with this library; if not, see . - */ - - #include "config.h" - - #include - #include - - #include "goaidentity.h" - - G_DEFINE_INTERFACE (GoaIdentity, goa_identity, G_TYPE_OBJECT); - - static void - goa_identity_default_init (GoaIdentityInterface *interface) - { - g_object_interface_install_property (interface, - g_param_spec_string ("identifier", - "identifier", - "identifier", - NULL, G_PARAM_READABLE)); - g_object_interface_install_property (interface, - g_param_spec_boolean ("is-signed-in", - "Is signed in", - "Whether or not identity is currently signed in", +@@ -40,6 +40,13 @@ goa_identity_default_init (GoaIdentityInterface *interface) FALSE, G_PARAM_READABLE)); g_object_interface_install_property (interface, @@ -68,65 +41,11 @@ index 2fc491b..2904e2a 100644 g_param_spec_int64 ("expiration-timestamp", "Expiration Timestamp", "A timestamp of when the identities credentials expire", - -1, - G_MAXINT64, - -1, G_PARAM_READABLE)); - } - - GQuark - goa_identity_error_quark (void) - { - static GQuark error_quark = 0; - - if (error_quark == 0) - { - error_quark = g_quark_from_static_string ("goa-identity-error"); - } - - return error_quark; - } - - const char * - goa_identity_get_identifier (GoaIdentity *self) - { - return GOA_IDENTITY_GET_IFACE (self)->get_identifier (self); - } - - gboolean - goa_identity_is_signed_in (GoaIdentity *self) - { diff --git a/src/goaidentity/goakerberosidentity.c b/src/goaidentity/goakerberosidentity.c -index 4370a09..6865535 100644 +index 1ce5079b6194..f43978d49ebf 100644 --- a/src/goaidentity/goakerberosidentity.c +++ b/src/goaidentity/goakerberosidentity.c -@@ -22,86 +22,89 @@ - #include "goakerberosidentity.h" - #include "goakerberosidentityinquiry.h" - #include "goaalarm.h" - - #include - #include - #include - - #include - #include - #include - - typedef enum - { - VERIFICATION_LEVEL_UNVERIFIED, - VERIFICATION_LEVEL_ERROR, - VERIFICATION_LEVEL_EXISTS, - VERIFICATION_LEVEL_SIGNED_IN - } VerificationLevel; - - struct _GoaKerberosIdentityPrivate - { - krb5_context kerberos_context; - krb5_ccache credentials_cache; - - char *identifier; - guint identifier_idle_id; +@@ -49,6 +49,8 @@ struct _GoaKerberosIdentityPrivate char *preauth_identity_source; @@ -135,26 +54,7 @@ index 4370a09..6865535 100644 krb5_timestamp expiration_time; guint expiration_time_idle_id; - GoaAlarm *expiration_alarm; - GoaAlarm *expiring_alarm; - GoaAlarm *renewal_alarm; - - VerificationLevel cached_verification_level; - guint is_signed_in_idle_id; - }; - - enum - { - EXPIRING, - EXPIRED, - UNEXPIRED, - NEEDS_RENEWAL, - NEEDS_REFRESH, - NUMBER_OF_SIGNALS, - }; - - enum - { +@@ -75,6 +77,7 @@ enum PROP_0, PROP_IDENTIFIER, PROP_IS_SIGNED_IN, @@ -162,61 +62,7 @@ index 4370a09..6865535 100644 PROP_EXPIRATION_TIMESTAMP }; - static guint signals[NUMBER_OF_SIGNALS] = { 0 }; - - static void identity_interface_init (GoaIdentityInterface *interface); - static void initable_interface_init (GInitableIface *interface); - static void reset_alarms (GoaKerberosIdentity *self); - static void clear_alarms (GoaKerberosIdentity *self); - static gboolean goa_kerberos_identity_is_signed_in (GoaIdentity *identity); - static void set_error_from_krb5_error_code (GoaKerberosIdentity *self, - GError **error, - gint code, - krb5_error_code error_code, - const char *format, - ...); - - G_LOCK_DEFINE_STATIC (identity_lock); - - G_DEFINE_TYPE_WITH_CODE (GoaKerberosIdentity, - goa_kerberos_identity, - G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, - initable_interface_init) - G_IMPLEMENT_INTERFACE (GOA_TYPE_IDENTITY, - identity_interface_init)); - static void - goa_kerberos_identity_dispose (GObject *object) - { - GoaKerberosIdentity *self = GOA_KERBEROS_IDENTITY (object); -@@ -121,60 +124,65 @@ goa_kerberos_identity_finalize (GObject *object) - { - GoaKerberosIdentity *self = GOA_KERBEROS_IDENTITY (object); - - g_free (self->priv->identifier); - - if (self->priv->credentials_cache != NULL) - krb5_cc_close (self->priv->kerberos_context, self->priv->credentials_cache); - - G_OBJECT_CLASS (goa_kerberos_identity_parent_class)->finalize (object); - } - - static void - goa_kerberos_identity_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *param_spec) - { - GoaKerberosIdentity *self = GOA_KERBEROS_IDENTITY (object); - - switch (property_id) - { - case PROP_IDENTIFIER: - G_LOCK (identity_lock); - g_value_set_string (value, self->priv->identifier); - G_UNLOCK (identity_lock); - break; - case PROP_IS_SIGNED_IN: +@@ -148,6 +151,11 @@ goa_kerberos_identity_get_property (GObject *object, g_value_set_boolean (value, goa_kerberos_identity_is_signed_in (GOA_IDENTITY (self))); break; @@ -228,61 +74,7 @@ index 4370a09..6865535 100644 case PROP_EXPIRATION_TIMESTAMP: G_LOCK (identity_lock); g_value_set_int64 (value, (gint64) self->priv->expiration_time); - G_UNLOCK (identity_lock); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, param_spec); - break; - } - } - - static void - goa_kerberos_identity_class_init (GoaKerberosIdentityClass *klass) - { - GObjectClass *object_class; - - object_class = G_OBJECT_CLASS (klass); - - object_class->dispose = goa_kerberos_identity_dispose; - object_class->finalize = goa_kerberos_identity_finalize; - object_class->get_property = goa_kerberos_identity_get_property; - - g_type_class_add_private (klass, sizeof (GoaKerberosIdentityPrivate)); - - signals[EXPIRING] = g_signal_new ("expiring", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, - NULL, -@@ -194,60 +202,63 @@ goa_kerberos_identity_class_init (GoaKerberosIdentityClass *klass) - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, - NULL, - NULL, - G_TYPE_NONE, - 0); - signals[NEEDS_RENEWAL] = g_signal_new ("needs-renewal", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, - NULL, - NULL, - G_TYPE_NONE, - 0); - signals[NEEDS_REFRESH] = g_signal_new ("needs-refresh", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, - NULL, - NULL, - G_TYPE_NONE, - 0); - +@@ -221,6 +229,9 @@ goa_kerberos_identity_class_init (GoaKerberosIdentityClass *klass) g_object_class_override_property (object_class, PROP_IDENTIFIER, "identifier"); g_object_class_override_property (object_class, PROP_IS_SIGNED_IN, "is-signed-in"); g_object_class_override_property (object_class, @@ -292,61 +84,7 @@ index 4370a09..6865535 100644 PROP_EXPIRATION_TIMESTAMP, "expiration-timestamp"); - } - - static char * - get_identifier (GoaKerberosIdentity *self, - GError **error) - { - krb5_principal principal; - krb5_error_code error_code; - char *unparsed_name; - char *identifier = NULL; - - if (self->priv->credentials_cache == NULL) - return NULL; - - error_code = krb5_cc_get_principal (self->priv->kerberos_context, - self->priv->credentials_cache, - &principal); - - if (error_code != 0) - { - if (error_code == KRB5_CC_END) - { - set_error_from_krb5_error_code (self, - error, - GOA_IDENTITY_ERROR_CREDENTIALS_UNAVAILABLE, - error_code, - _ -@@ -546,207 +557,233 @@ on_notify_queued (NotifyRequest *request) - - return FALSE; - } - - static void - queue_notify (GoaKerberosIdentity *self, - guint *idle_id, - const char *property_name) - { - NotifyRequest *request; - - if (*idle_id != 0) - { - return; - } - - request = g_slice_new0 (NotifyRequest); - request->self = g_object_ref (self); - request->idle_id = idle_id; - request->property_name = property_name; - - *idle_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, - (GSourceFunc) - on_notify_queued, - request, - (GDestroyNotify) - clear_idle_id); +@@ -573,6 +584,23 @@ queue_notify (GoaKerberosIdentity *self, } static void @@ -370,19 +108,7 @@ index 4370a09..6865535 100644 set_expiration_time (GoaKerberosIdentity *self, krb5_timestamp expiration_time) { - G_LOCK (identity_lock); - if (self->priv->expiration_time != expiration_time) - { - self->priv->expiration_time = expiration_time; - G_UNLOCK (identity_lock); - queue_notify (self, - &self->priv->expiration_time_idle_id, - "expiration-timestamp"); - G_LOCK (identity_lock); - } - G_UNLOCK (identity_lock); - } - +@@ -592,6 +620,7 @@ set_expiration_time (GoaKerberosIdentity *self, static gboolean credentials_are_expired (GoaKerberosIdentity *self, krb5_creds *credentials, @@ -390,7 +116,7 @@ index 4370a09..6865535 100644 krb5_timestamp *expiration_time) { krb5_timestamp current_time; - +@@ -599,11 +628,17 @@ credentials_are_expired (GoaKerberosIdentity *self, current_time = get_current_time (self); G_LOCK (identity_lock); @@ -409,16 +135,7 @@ index 4370a09..6865535 100644 { return TRUE; } - - return FALSE; - } - - static VerificationLevel - verify_identity (GoaKerberosIdentity *self, - char **preauth_identity_source, - GError **error) - { - krb5_principal principal = NULL; +@@ -620,6 +655,7 @@ verify_identity (GoaKerberosIdentity *self, krb5_cc_cursor cursor; krb5_creds credentials; krb5_error_code error_code; @@ -426,51 +143,7 @@ index 4370a09..6865535 100644 krb5_timestamp expiration_time = 0; VerificationLevel verification_level = VERIFICATION_LEVEL_UNVERIFIED; - if (self->priv->credentials_cache == NULL) - goto out; - - error_code = krb5_cc_get_principal (self->priv->kerberos_context, - self->priv->credentials_cache, - &principal); - - if (error_code != 0) - { - if (error_code == KRB5_CC_END || error_code == KRB5_FCC_NOFILE) - goto out; - - set_error_from_krb5_error_code (self, - error, - GOA_IDENTITY_ERROR_NOT_FOUND, - error_code, - _("Could not find identity in " - "credential cache: %k")); - verification_level = VERIFICATION_LEVEL_ERROR; - goto out; - } - - error_code = krb5_cc_start_seq_get (self->priv->kerberos_context, - self->priv->credentials_cache, &cursor); - if (error_code != 0) - { - set_error_from_krb5_error_code (self, - error, - GOA_IDENTITY_ERROR_CREDENTIALS_UNAVAILABLE, - error_code, - _("Could not find identity " - "credentials in cache: %k")); - - verification_level = VERIFICATION_LEVEL_ERROR; - goto out; - } - - verification_level = VERIFICATION_LEVEL_UNVERIFIED; - - error_code = krb5_cc_next_cred (self->priv->kerberos_context, - self->priv->credentials_cache, - &cursor, - &credentials); - - while (error_code == 0) +@@ -671,7 +707,7 @@ verify_identity (GoaKerberosIdentity *self, { if (credentials_validate_existence (self, principal, &credentials)) { @@ -479,48 +152,7 @@ index 4370a09..6865535 100644 verification_level = VERIFICATION_LEVEL_SIGNED_IN; else verification_level = VERIFICATION_LEVEL_EXISTS; - } - else - { - snoop_preauth_identity_from_credentials (self, &credentials, preauth_identity_source); - } - - krb5_free_cred_contents (self->priv->kerberos_context, &credentials); - - error_code = krb5_cc_next_cred (self->priv->kerberos_context, - self->priv->credentials_cache, - &cursor, - &credentials); - } - - if (error_code != KRB5_CC_END) - { - verification_level = VERIFICATION_LEVEL_ERROR; - - set_error_from_krb5_error_code (self, - error, - GOA_IDENTITY_ERROR_ENUMERATING_CREDENTIALS, - error_code, - _("Could not sift through identity " - "credentials in cache: %k")); - goto end_sequence; - } - - end_sequence: - error_code = krb5_cc_end_seq_get (self->priv->kerberos_context, - self->priv->credentials_cache, - &cursor); - - if (error_code != 0) - { - verification_level = VERIFICATION_LEVEL_ERROR; - - set_error_from_krb5_error_code (self, - error, - GOA_IDENTITY_ERROR_ENUMERATING_CREDENTIALS, - error_code, - _("Could not finish up sifting through " - "identity credentials in cache: %k")); +@@ -720,6 +756,7 @@ verify_identity (GoaKerberosIdentity *self, goto out; } out: @@ -528,61 +160,7 @@ index 4370a09..6865535 100644 set_expiration_time (self, expiration_time); if (principal != NULL) - krb5_free_principal (self->priv->kerberos_context, principal); - return verification_level; - } - - static gboolean - goa_kerberos_identity_is_signed_in (GoaIdentity *identity) - { - GoaKerberosIdentity *self = GOA_KERBEROS_IDENTITY (identity); - gboolean is_signed_in = FALSE; - - G_LOCK (identity_lock); - if (self->priv->cached_verification_level == VERIFICATION_LEVEL_SIGNED_IN) - is_signed_in = TRUE; - G_UNLOCK (identity_lock); - - return is_signed_in; - } - - static void - identity_interface_init (GoaIdentityInterface *interface) - { - interface->get_identifier = goa_kerberos_identity_get_identifier; - interface->is_signed_in = goa_kerberos_identity_is_signed_in; - } - - static void - on_expiration_alarm_fired (GoaAlarm *alarm, -@@ -895,90 +932,90 @@ connect_alarm_signals (GoaKerberosIdentity *self) - { - g_signal_connect (G_OBJECT (self->priv->renewal_alarm), - "fired", - G_CALLBACK (on_renewal_alarm_fired), - self); - g_signal_connect (G_OBJECT (self->priv->renewal_alarm), - "rearmed", - G_CALLBACK (on_renewal_alarm_rearmed), - self); - g_signal_connect (G_OBJECT (self->priv->expiring_alarm), - "fired", - G_CALLBACK (on_expiring_alarm_fired), - self); - g_signal_connect (G_OBJECT (self->priv->expiring_alarm), - "rearmed", - G_CALLBACK (on_expiring_alarm_rearmed), - self); - g_signal_connect (G_OBJECT (self->priv->expiration_alarm), - "fired", - G_CALLBACK (on_expiration_alarm_fired), - self); - g_signal_connect (G_OBJECT (self->priv->expiration_alarm), - "rearmed", - G_CALLBACK (on_expiration_alarm_rearmed), - self); - } - +@@ -922,18 +959,18 @@ connect_alarm_signals (GoaKerberosIdentity *self) static void reset_alarms (GoaKerberosIdentity *self) { @@ -606,7 +184,7 @@ index 4370a09..6865535 100644 /* Let the user reauthenticate 10 min before expiration */ expiring_time = g_date_time_add_minutes (expiration_time, -10); - +@@ -941,8 +978,7 @@ reset_alarms (GoaKerberosIdentity *self) /* Try to quietly auto-renew halfway through so in ideal configurations * the ticket is never more than halfway to expired */ @@ -616,9 +194,7 @@ index 4370a09..6865535 100644 disconnect_alarm_signals (self); - reset_alarm (self, &self->priv->renewal_alarm, renewal_time); - reset_alarm (self, &self->priv->expiring_alarm, expiring_time); - reset_alarm (self, &self->priv->expiration_alarm, expiration_time); +@@ -952,6 +988,7 @@ reset_alarms (GoaKerberosIdentity *self) g_date_time_unref (renewal_time); g_date_time_unref (expiring_time); @@ -626,132 +202,14 @@ index 4370a09..6865535 100644 g_date_time_unref (expiration_time); connect_alarm_signals (self); } - - static void - clear_alarms (GoaKerberosIdentity *self) - { - disconnect_alarm_signals (self); - clear_alarm_and_unref_on_idle (self, &self->priv->renewal_alarm); - clear_alarm_and_unref_on_idle (self, &self->priv->expiring_alarm); - clear_alarm_and_unref_on_idle (self, &self->priv->expiration_alarm); - } - - static gboolean - goa_kerberos_identity_initable_init (GInitable *initable, - GCancellable *cancellable, - GError **error) - { - GoaKerberosIdentity *self = GOA_KERBEROS_IDENTITY (initable); - GError *verification_error; - - if (g_cancellable_set_error_if_cancelled (cancellable, error)) - return FALSE; - - if (self->priv->identifier == NULL) - { - self->priv->identifier = get_identifier (self, error); - - if (self->priv->identifier != NULL) - queue_notify (self, &self->priv->identifier_idle_id, "identifier"); --- -2.5.0 - - -From 57757628e01dcd1d6ce9855bdad70d5f69757157 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Tue, 22 Sep 2015 14:41:05 -0400 -Subject: [PATCH 2/3] identity: don't ever nullify identifier - -credentials stored in the kernel keyring disappear after they expire. -This is is different from other credential caches, which hang around -but maintain an expired timestamp until kdestroy. Because the credentials -vanish, trying to read the principal from an previously existing credential -cache, will yield NULL. - -This can lead to a crash in goa which never expects the identifier of an -identity object to be NULL. - -This commit makes sure we retain the old identifier in the event the -credential cache gets wiped. ---- - src/goaidentity/goakerberosidentity.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/goaidentity/goakerberosidentity.c b/src/goaidentity/goakerberosidentity.c -index 6865535..f43978d 100644 ---- a/src/goaidentity/goakerberosidentity.c -+++ b/src/goaidentity/goakerberosidentity.c -@@ -1355,61 +1355,61 @@ goa_kerberos_identity_sign_in (GoaKerberosIdentity *self, - goto done; - } - - if (destroy_notify) - destroy_notify (inquiry_data); - sign_in_operation_free (operation); - - if (!goa_kerberos_identity_update_credentials (self, - principal, - &new_credentials, - error)) - { - krb5_free_principal (self->priv->kerberos_context, principal); - goto done; - } - krb5_free_principal (self->priv->kerberos_context, principal); - - g_debug ("GoaKerberosIdentity: identity signed in"); - signed_in = TRUE; - done: - - return signed_in; - } - - static void - update_identifier (GoaKerberosIdentity *self, GoaKerberosIdentity *new_identity) - { - char *new_identifier; - - new_identifier = get_identifier (self, NULL); -- if (g_strcmp0 (self->priv->identifier, new_identifier) != 0) -+ if (g_strcmp0 (self->priv->identifier, new_identifier) != 0 && new_identifier != NULL) - { - g_free (self->priv->identifier); - self->priv->identifier = new_identifier; - queue_notify (self, &self->priv->identifier_idle_id, "identifier"); - } - else - { - g_free (new_identifier); - } - } - - void - goa_kerberos_identity_update (GoaKerberosIdentity *self, - GoaKerberosIdentity *new_identity) - { - VerificationLevel verification_level; - char *preauth_identity_source = NULL; - - if (self->priv->credentials_cache != NULL) - krb5_cc_close (self->priv->kerberos_context, self->priv->credentials_cache); - - krb5_cc_dup (new_identity->priv->kerberos_context, - new_identity->priv->credentials_cache, - &self->priv->credentials_cache); - - G_LOCK (identity_lock); - update_identifier (self, new_identity); - G_UNLOCK (identity_lock); - - verification_level = verify_identity (self, &preauth_identity_source, NULL); -- 2.5.0 -From 8d8a923530402fef8dd04b5b4efd349c45118e13 Mon Sep 17 00:00:00 2001 +From d3f7bcc56592a3113c1cde55bf67c44514acc7f9 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Tue, 22 Sep 2015 14:38:29 -0400 -Subject: [PATCH 3/3] identity: don't ignore almost all renewal requests +Subject: [PATCH 2/2] identity: don't ignore almost all renewal requests There's a bug in the code where we ignore all renewal requests for objects we already know about. @@ -767,37 +225,10 @@ This was clearly the original intention of the buggy code. 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/goaidentity/goaidentityservice.c b/src/goaidentity/goaidentityservice.c -index 6b6225a..bb5d3a7 100644 +index 6b6225adbc61..bb5d3a7dbe25 100644 --- a/src/goaidentity/goaidentityservice.c +++ b/src/goaidentity/goaidentityservice.c -@@ -714,70 +714,71 @@ static void - on_identity_renewed (GoaIdentityManager *manager, - GAsyncResult *result, - GoaIdentityService *self) - { - GError *error; - - error = NULL; - goa_identity_manager_renew_identity_finish (manager, result, &error); - - if (error != NULL) - { - g_debug ("GoaIdentityService: could not renew identity: %s", - error->message); - g_error_free (error); - return; - } - - g_debug ("GoaIdentityService: identity renewed"); - } - - static void - on_identity_needs_renewal (GoaIdentityManager *identity_manager, - GoaIdentity *identity, - GoaIdentityService *self) - { - const char *principal; - GoaObject *object; +@@ -741,16 +741,17 @@ on_identity_needs_renewal (GoaIdentityManager *identity_manager, principal = goa_identity_get_identifier (identity); @@ -819,33 +250,6 @@ index 6b6225a..bb5d3a7 100644 goa_identity_manager_renew_identity (GOA_IDENTITY_MANAGER (self->priv->identity_manager), identity, - NULL, - (GAsyncReadyCallback) - on_identity_renewed, - self); - } - - static void - on_identity_signed_in (GoaIdentityManager *manager, - GAsyncResult *result, - GSimpleAsyncResult *operation_result) - { - GError *error; - GoaIdentity *identity; - - error = NULL; - identity = goa_identity_manager_sign_identity_in_finish (manager, result, &error); - - if (error != NULL) - { - g_debug ("GoaIdentityService: could not sign in identity: %s", - error->message); - g_simple_async_result_take_error (operation_result, error); - } - else - { - g_simple_async_result_set_op_res_gpointer (operation_result, - g_object_ref (identity), -- 2.5.0 diff --git a/SOURCES/kerberos-separate-process.patch b/SOURCES/kerberos-separate-process.patch index c21a5a9..1a1f39b 100644 --- a/SOURCES/kerberos-separate-process.patch +++ b/SOURCES/kerberos-separate-process.patch @@ -1,4 +1,4 @@ -From a905f21aeef808b3ec7d9a343953551334acdc18 Mon Sep 17 00:00:00 2001 +From 2c351af58d1ba5581a95ed02d38fdc8dd904ad7b Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Tue, 28 Oct 2014 17:16:18 -0400 Subject: [PATCH 1/2] kerberos: maintain one long-lasting object manager client @@ -29,7 +29,7 @@ leverages the sync code, in a thread. 1 file changed, 345 insertions(+), 618 deletions(-) diff --git a/src/goabackend/goakerberosprovider.c b/src/goabackend/goakerberosprovider.c -index f9c54cd..2eb6b67 100644 +index f9c54cd4f79c..2eb6b677ab22 100644 --- a/src/goabackend/goakerberosprovider.c +++ b/src/goabackend/goakerberosprovider.c @@ -41,8 +41,6 @@ struct _GoaKerberosProvider @@ -1116,10 +1116,10 @@ index f9c54cd..2eb6b67 100644 static void -- -2.1.0 +2.5.0 -From 9dc739548d3cd27df2b9bce46099d14267d6032a Mon Sep 17 00:00:00 2001 +From 2dbd414c16d8654f0cfccb54fede644b8f3216db Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Tue, 28 Oct 2014 17:10:49 -0400 Subject: [PATCH 2/2] identity: separate identity service off into its own @@ -1150,7 +1150,7 @@ the whole online accounts daemon. create mode 100644 src/goaidentity/main.c diff --git a/data/Makefile.am b/data/Makefile.am -index cb30eb8..fb68063 100644 +index cb30eb8d1391..fb68063c8234 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -14,9 +14,14 @@ gsettings_SCHEMAS = $(gsettings_in_files:.xml.in=.xml) @@ -1179,7 +1179,7 @@ index cb30eb8..fb68063 100644 clean-local : diff --git a/data/org.gnome.Identity.service.in b/data/org.gnome.Identity.service.in new file mode 100644 -index 0000000..bd3b032 +index 000000000000..bd3b03225ab6 --- /dev/null +++ b/data/org.gnome.Identity.service.in @@ -0,0 +1,3 @@ @@ -1187,7 +1187,7 @@ index 0000000..bd3b032 +Name=org.gnome.Identity +Exec=@libexecdir@/goa-identity-service diff --git a/src/daemon/Makefile.am b/src/daemon/Makefile.am -index 9fdb115..8f5352f 100644 +index 9fdb11538a4e..8f5352fad39e 100644 --- a/src/daemon/Makefile.am +++ b/src/daemon/Makefile.am @@ -48,14 +48,6 @@ goa_daemon_LDADD = \ @@ -1206,7 +1206,7 @@ index 9fdb115..8f5352f 100644 rm -f *~ diff --git a/src/daemon/goadaemon.c b/src/daemon/goadaemon.c -index 9d5543d..30016f5 100644 +index 8074f201ef46..1aa0f18aee45 100644 --- a/src/daemon/goadaemon.c +++ b/src/daemon/goadaemon.c @@ -25,9 +25,6 @@ @@ -1294,7 +1294,7 @@ index 9d5543d..30016f5 100644 } diff --git a/src/goaidentity/Makefile.am b/src/goaidentity/Makefile.am -index 8e11f6d..537287a 100644 +index 8e11f6d596da..537287a2cca3 100644 --- a/src/goaidentity/Makefile.am +++ b/src/goaidentity/Makefile.am @@ -47,6 +47,7 @@ identity_sources = \ @@ -1335,7 +1335,7 @@ index 8e11f6d..537287a 100644 $(GTK_LIBS) \ $(KRB5_LIBS) \ diff --git a/src/goaidentity/goaidentityservice.c b/src/goaidentity/goaidentityservice.c -index 38bbde6..6b6225a 100644 +index 38bbde6a7d93..6b6225adbc61 100644 --- a/src/goaidentity/goaidentityservice.c +++ b/src/goaidentity/goaidentityservice.c @@ -1757,7 +1757,7 @@ on_name_lost (GDBusConnection *connection, @@ -1349,7 +1349,7 @@ index 38bbde6..6b6225a 100644 gboolean diff --git a/src/goaidentity/main.c b/src/goaidentity/main.c new file mode 100644 -index 0000000..2de35ac +index 000000000000..2de35acfc561 --- /dev/null +++ b/src/goaidentity/main.c @@ -0,0 +1,59 @@ @@ -1413,5 +1413,5 @@ index 0000000..2de35ac + return ret; +} -- -2.1.0 +2.5.0 diff --git a/SOURCES/kerberos-smartcard.patch b/SOURCES/kerberos-smartcard.patch index 0660af1..c52c4e7 100644 --- a/SOURCES/kerberos-smartcard.patch +++ b/SOURCES/kerberos-smartcard.patch @@ -1,4 +1,4 @@ -From 3753904f1de123a724438bf7f0c58aac00ce4ef4 Mon Sep 17 00:00:00 2001 +From fa3d138dbfe874fda8ede8b1153cfaa92dc404e4 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Tue, 21 Oct 2014 10:38:17 -0400 Subject: [PATCH 1/2] ticketing: add new details property @@ -14,7 +14,7 @@ associated with smartcard backed kerberos accounts. 1 file changed, 2 insertions(+) diff --git a/data/dbus-interfaces.xml b/data/dbus-interfaces.xml -index 5bf26e9..fa8b18c 100644 +index 5bf26e9dca69..fa8b18c9a817 100644 --- a/data/dbus-interfaces.xml +++ b/data/dbus-interfaces.xml @@ -726,6 +726,8 @@ @@ -27,10 +27,10 @@ index 5bf26e9..fa8b18c 100644 GetTicket: -- -2.1.0 +2.5.0 -From 1544883b52453ba8e69e78b5bdacf7a57053326c Mon Sep 17 00:00:00 2001 +From 31c832233f457cf5139e21b3bf3f881bb2dfbece Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Tue, 21 Oct 2014 10:46:50 -0400 Subject: [PATCH 2/2] kerberos: Support refreshing smartcard authenticated @@ -57,7 +57,7 @@ https://bugzilla.gnome.org/show_bug.cgi?id=739594 7 files changed, 146 insertions(+), 7 deletions(-) diff --git a/src/goabackend/goakerberosprovider.c b/src/goabackend/goakerberosprovider.c -index b2958b2..f9c54cd 100644 +index b2958b22b80b..f9c54cd4f79c 100644 --- a/src/goabackend/goakerberosprovider.c +++ b/src/goabackend/goakerberosprovider.c @@ -370,6 +370,7 @@ on_secret_keys_exchanged_for_sign_in (GoaKerberosProvider *self, @@ -203,7 +203,7 @@ index b2958b2..f9c54cd 100644 (GAsyncReadyCallback) on_initial_sign_in_done, diff --git a/src/goaidentity/goaidentitymanager.c b/src/goaidentity/goaidentitymanager.c -index 40d2225..22dcd97 100644 +index 40d22254d621..22dcd9797cc5 100644 --- a/src/goaidentity/goaidentitymanager.c +++ b/src/goaidentity/goaidentitymanager.c @@ -202,6 +202,7 @@ void @@ -223,7 +223,7 @@ index 40d2225..22dcd97 100644 inquiry_func, inquiry_data, diff --git a/src/goaidentity/goaidentitymanager.h b/src/goaidentity/goaidentitymanager.h -index 89e6b6e..755053a 100644 +index 89e6b6e18bab..755053a9d389 100644 --- a/src/goaidentity/goaidentitymanager.h +++ b/src/goaidentity/goaidentitymanager.h @@ -77,6 +77,7 @@ struct _GoaIdentityManagerInterface @@ -243,7 +243,7 @@ index 89e6b6e..755053a 100644 GoaIdentityInquiryFunc inquiry_func, gpointer inquiry_data, diff --git a/src/goaidentity/goaidentityservice.c b/src/goaidentity/goaidentityservice.c -index 06fb946..38bbde6 100644 +index 06fb946b5bf8..38bbde6a7d93 100644 --- a/src/goaidentity/goaidentityservice.c +++ b/src/goaidentity/goaidentityservice.c @@ -60,6 +60,7 @@ static void @@ -354,7 +354,7 @@ index 06fb946..38bbde6 100644 (GoaIdentityInquiryFunc) on_identity_inquiry, diff --git a/src/goaidentity/goakerberosidentity.c b/src/goaidentity/goakerberosidentity.c -index d501a59..4370a09 100644 +index 365ced95bac6..1ce5079b6194 100644 --- a/src/goaidentity/goakerberosidentity.c +++ b/src/goaidentity/goakerberosidentity.c @@ -47,6 +47,8 @@ struct _GoaKerberosIdentityPrivate @@ -512,7 +512,7 @@ index d501a59..4370a09 100644 { if (self->priv->cached_verification_level == VERIFICATION_LEVEL_SIGNED_IN && diff --git a/src/goaidentity/goakerberosidentity.h b/src/goaidentity/goakerberosidentity.h -index 1e24796..8d2860a 100644 +index 1e247967b5df..8d2860afa89f 100644 --- a/src/goaidentity/goakerberosidentity.h +++ b/src/goaidentity/goakerberosidentity.h @@ -66,6 +66,7 @@ GoaIdentity *goa_kerberos_identity_new (krb5_context kerberos_context, @@ -531,7 +531,7 @@ index 1e24796..8d2860a 100644 G_END_DECLS #endif /* __GOA_KERBEROS_IDENTITY_H__ */ diff --git a/src/goaidentity/goakerberosidentitymanager.c b/src/goaidentity/goakerberosidentitymanager.c -index c9796ad..a1898c9 100644 +index c9796add8412..a1898c99d703 100644 --- a/src/goaidentity/goakerberosidentitymanager.c +++ b/src/goaidentity/goakerberosidentitymanager.c @@ -81,6 +81,7 @@ typedef struct @@ -585,5 +585,5 @@ index c9796ad..a1898c9 100644 operation->inquiry_func = inquiry_func; operation->inquiry_data = inquiry_data; -- -2.1.0 +2.5.0 diff --git a/SOURCES/kerberos-telepathy-stopping-goa-daemon-removes-account.patch b/SOURCES/kerberos-telepathy-stopping-goa-daemon-removes-account.patch new file mode 100644 index 0000000..12add92 --- /dev/null +++ b/SOURCES/kerberos-telepathy-stopping-goa-daemon-removes-account.patch @@ -0,0 +1,4270 @@ +From 6bb9425ba858b2e0ecb128af88e263e887efda0b Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Fri, 20 May 2016 14:21:07 +0200 +Subject: [PATCH 01/22] provider: Export ensure_builtins_loaded as internal API + +... because we want to use it inside GoaDaemon also. + +https://bugzilla.gnome.org/show_bug.cgi?id=766733 +--- + src/goabackend/goaprovider-priv.h | 2 ++ + src/goabackend/goaprovider.c | 12 ++++++------ + 2 files changed, 8 insertions(+), 6 deletions(-) + +diff --git a/src/goabackend/goaprovider-priv.h b/src/goabackend/goaprovider-priv.h +index 540da2eee4a7..dfede1b2bb97 100644 +--- a/src/goabackend/goaprovider-priv.h ++++ b/src/goabackend/goaprovider-priv.h +@@ -119,6 +119,8 @@ struct _GoaProviderClass + */ + #define GOA_PROVIDER_FACTORY_EXTENSION_POINT_NAME "goa-backend-provider-factory" + ++void goa_provider_ensure_builtins_loaded (void); ++ + void goa_provider_ensure_extension_points_registered (void); + + G_END_DECLS +diff --git a/src/goabackend/goaprovider.c b/src/goabackend/goaprovider.c +index eb221196eddc..e6cac23d6adc 100644 +--- a/src/goabackend/goaprovider.c ++++ b/src/goabackend/goaprovider.c +@@ -802,8 +802,8 @@ static struct + { NULL, NULL } + }; + +-static void +-ensure_builtins_loaded (void) ++void ++goa_provider_ensure_builtins_loaded (void) + { + static gsize once_init_value = 0; + +@@ -892,7 +892,7 @@ goa_provider_get_for_provider_type (const gchar *provider_type) + + g_return_val_if_fail (provider_type != NULL, NULL); + +- ensure_builtins_loaded (); ++ goa_provider_ensure_builtins_loaded (); + + ret = NULL; + +@@ -1048,7 +1048,7 @@ goa_provider_get_all (GAsyncReadyCallback callback, + GetAllData *data; + gint i; + +- ensure_builtins_loaded (); ++ goa_provider_ensure_builtins_loaded (); + + data = g_slice_new0 (GetAllData); + data->result = g_simple_async_result_new (NULL, callback, user_data, +@@ -1063,8 +1063,8 @@ goa_provider_get_all (GAsyncReadyCallback callback, + { + GIOExtension *extension = l->data; + /* The extensions are loaded in the reverse order we used in +- * ensure_builtins_loaded, so we need to push extension if front of +- * the already loaded ones. */ ++ * goa_provider_ensure_builtins_loaded, so we need to push ++ * extension if front of the already loaded ones. */ + g_queue_push_head (&data->ret, g_object_new (g_io_extension_get_type (extension), NULL)); + } + +-- +2.5.5 + + +From fed8f107d2d864596554f79137f78945bb0d8ade Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Fri, 20 May 2016 14:55:40 +0200 +Subject: [PATCH 02/22] daemon: Abstract the way we initialize the Kerberos + provider + +The Kerberos backend needs to perform some class-wide (ie. not +instance-specific) initialization when goa-daemon starts. This code is +embedded into the class' type registration code. + +There is no reason to call out to the Kerberos provider explicitly by +creating a dummy instance. The provider class will perform all +necessary initialization at the time of extension registration. Merely +ensuring the extensions are registered is better because it makes the +backend implementation details more opaque. + +https://bugzilla.gnome.org/show_bug.cgi?id=766733 +--- + src/daemon/goadaemon.c | 27 +++------------------------ + src/goabackend/goakerberosprovider.c | 1 + + 2 files changed, 4 insertions(+), 24 deletions(-) + +diff --git a/src/daemon/goadaemon.c b/src/daemon/goadaemon.c +index 213f154c12aa..05ccb04c9ba5 100644 +--- a/src/daemon/goadaemon.c ++++ b/src/daemon/goadaemon.c +@@ -24,6 +24,7 @@ + + #include "goadaemon.h" + #include "goabackend/goabackend.h" ++#include "goabackend/goaprovider-priv.h" + #include "goabackend/goautils.h" + + struct _GoaDaemon +@@ -200,26 +201,6 @@ on_network_monitor_network_changed (GoaDaemon *self, gboolean available) + queue_check_credentials (self); + } + +-#ifdef GOA_KERBEROS_ENABLED +-static void +-activate_identity_service (GoaDaemon *self) +-{ +- GoaProvider *provider; +- +- /* We activate the identity service implicitly by using the kerberos +- * backend. This way if the kerberos backend isn't enabled, we don't +- * end up starting the identity service needlessly +- */ +- provider = goa_provider_get_for_provider_type (GOA_KERBEROS_NAME); +- +- if (provider != NULL) +- { +- g_debug ("activated kerberos provider"); +- g_object_unref (provider); +- } +-} +-#endif +- + static void + goa_daemon_init (GoaDaemon *self) + { +@@ -233,6 +214,8 @@ goa_daemon_init (GoaDaemon *self) + goa_error_domain = GOA_ERROR; + goa_error_domain; /* shut up -Wunused-but-set-variable */ + ++ goa_provider_ensure_builtins_loaded (); ++ + /* TODO: maybe nicer to pass in a GDBusConnection* construct property */ + self->connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + +@@ -279,10 +262,6 @@ goa_daemon_init (GoaDaemon *self) + g_dbus_object_manager_server_set_connection (self->object_manager, self->connection); + + queue_check_credentials (self); +- +-#ifdef GOA_KERBEROS_ENABLED +- activate_identity_service (self); +-#endif + } + + static void +diff --git a/src/goabackend/goakerberosprovider.c b/src/goabackend/goakerberosprovider.c +index a3a9bd9f5369..9d6ddd65f995 100644 +--- a/src/goabackend/goakerberosprovider.c ++++ b/src/goabackend/goakerberosprovider.c +@@ -100,6 +100,7 @@ goa_kerberos_provider_module_init (void) + { + create_object_manager (); + create_identity_manager (); ++ g_debug ("activated kerberos provider"); + } + + static const gchar * +-- +2.5.5 + + +From de14a8ff62c34c4b2e77d29705ba373442031c4e Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Fri, 20 May 2016 16:25:44 +0200 +Subject: [PATCH 03/22] identity: Minor clean up + +There is no need to keep the GoaManager pointer as an instance +variable. We can just get it when adding the account. There are too +many manager-like variables flying around. This makes the code more +readable by keeping one of them closely tied to its context. + +https://bugzilla.gnome.org/show_bug.cgi?id=766733 +--- + src/goaidentity/goaidentityservice.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/src/goaidentity/goaidentityservice.c b/src/goaidentity/goaidentityservice.c +index bb5d3a7dbe25..2eda31d56e74 100644 +--- a/src/goaidentity/goaidentityservice.c ++++ b/src/goaidentity/goaidentityservice.c +@@ -51,7 +51,6 @@ struct _GoaIdentityServicePrivate + * is in process, we should able to use direct calls. + */ + GoaClient *client; +- GoaManager *accounts_manager; + }; + + static void identity_service_manager_interface_init (GoaIdentityServiceManagerIface *interface); +@@ -883,6 +882,7 @@ add_temporary_account (GoaIdentityService *self, + GSimpleAsyncResult *operation_result; + GVariantBuilder credentials; + GVariantBuilder details; ++ GoaManager *manager; + GoaObject *object; + + principal = goa_identity_get_identifier (identity); +@@ -927,7 +927,8 @@ add_temporary_account (GoaIdentityService *self, + g_strdup (principal), + g_object_ref (operation_result)); + +- goa_manager_call_add_account (self->priv->accounts_manager, ++ manager = goa_client_get_manager (self->priv->client); ++ goa_manager_call_add_account (manager, + "kerberos", + principal, + principal_for_display, +@@ -1700,8 +1701,6 @@ on_got_client (GoaClient *client, + goto out; + } + +- self->priv->accounts_manager = goa_client_get_manager (client); +- + self->priv->identity_manager = goa_kerberos_identity_manager_new (NULL, &error); + + if (self->priv->identity_manager == NULL) +-- +2.5.5 + + +From 860b8aee47db9e3558d78d69a17fe154e8e5145a Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Fri, 3 Jun 2016 17:36:42 +0200 +Subject: [PATCH 04/22] telepathy: Simplify the code by re-using the existing + GoaClient + +https://bugzilla.gnome.org/show_bug.cgi?id=767299 +--- + src/goabackend/goatelepathyprovider.c | 33 +++++---------------------------- + 1 file changed, 5 insertions(+), 28 deletions(-) + +diff --git a/src/goabackend/goatelepathyprovider.c b/src/goabackend/goatelepathyprovider.c +index a388b8a4e090..cb3c8dd02de6 100644 +--- a/src/goabackend/goatelepathyprovider.c ++++ b/src/goabackend/goatelepathyprovider.c +@@ -326,7 +326,7 @@ check_existing_goa_accounts (AddAccountData *data) + GList *l = NULL; + gboolean found = FALSE; + +- if (data->tp_account == NULL || data->goa_client == NULL) ++ if (data->tp_account == NULL) + return FALSE; + + goa_accounts = goa_client_get_accounts (data->goa_client); +@@ -365,31 +365,6 @@ goa_account_added_cb (GoaClient *client, + } + + static void +-goa_client_new_cb (GObject *object, +- GAsyncResult *result, +- gpointer user_data) +-{ +- AddAccountData *data = user_data; +- +- data->goa_client = goa_client_new_finish (result, &data->error); +- if (data->goa_client == NULL) +- { +- g_set_error (&data->error, +- GOA_ERROR, +- GOA_ERROR_FAILED, +- _("Failed to initialize a GOA client")); +- g_main_loop_quit (data->loop); +- return; +- } +- +- if (!check_existing_goa_accounts (data)) +- { +- data->goa_account_added_id = g_signal_connect (data->goa_client, +- "account-added", G_CALLBACK (goa_account_added_cb), data); +- } +-} +- +-static void + account_widget_close_cb (TpawAccountWidget *widget, + GtkResponseType response, + AddAccountData *data) +@@ -432,7 +407,10 @@ add_account (GoaProvider *provider, + data.dialog = dialog; + data.vbox = vbox; + +- goa_client_new (data.cancellable, goa_client_new_cb, &data); ++ data.goa_client = client; ++ data.goa_account_added_id = g_signal_connect (data.goa_client, ++ "account-added", G_CALLBACK (goa_account_added_cb), &data); ++ + wait_for_account_settings_ready (settings, data.loop); + + account_widget = tpaw_account_widget_new_for_protocol (settings, +@@ -488,7 +466,6 @@ out: + g_signal_handler_disconnect (data.goa_client, data.goa_account_added_id); + + g_clear_pointer (&data.loop, g_main_loop_unref); +- g_clear_object (&data.goa_client); + g_clear_object (&data.tp_account); + + return data.ret; +-- +2.5.5 + + +From 31b1d426a4be084d433ddbf7c7b6fd3c47083ec4 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Fri, 3 Jun 2016 19:44:45 +0200 +Subject: [PATCH 05/22] telepathy: Remove the unused GCancellable + +https://bugzilla.gnome.org/show_bug.cgi?id=767299 +--- + src/goabackend/goatelepathyprovider.c | 10 +--------- + 1 file changed, 1 insertion(+), 9 deletions(-) + +diff --git a/src/goabackend/goatelepathyprovider.c b/src/goabackend/goatelepathyprovider.c +index cb3c8dd02de6..ff509cc501fe 100644 +--- a/src/goabackend/goatelepathyprovider.c ++++ b/src/goabackend/goatelepathyprovider.c +@@ -269,7 +269,6 @@ get_provider_features (GoaProvider *provider) + typedef struct + { + GMainLoop *loop; +- GCancellable *cancellable; + GoaObject *ret; + GError *error; + +@@ -400,7 +399,6 @@ add_account (GoaProvider *provider, + } + + memset (&data, 0, sizeof (AddAccountData)); +- data.cancellable = g_cancellable_new (); + data.loop = g_main_loop_new (NULL, FALSE); + data.error = NULL; + data.provider = GOA_TELEPATHY_PROVIDER (provider); +@@ -444,7 +442,7 @@ add_account (GoaProvider *provider, + goto out; + } + +- if (data.ret == NULL && !g_cancellable_is_cancelled (data.cancellable)) ++ if (data.ret == NULL) + { + /* We wait for the account to be created */ + g_main_loop_run (data.loop); +@@ -456,12 +454,6 @@ out: + else + g_assert (data.ret != NULL); + +- if (data.cancellable != NULL) +- { +- g_cancellable_cancel (data.cancellable); +- g_object_unref (data.cancellable); +- } +- + if (data.goa_account_added_id) + g_signal_handler_disconnect (data.goa_client, data.goa_account_added_id); + +-- +2.5.5 + + +From 723ba9e231f2799bc0e15339585640b64fab36bd Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Fri, 3 Jun 2016 20:56:36 +0200 +Subject: [PATCH 06/22] telepathy: Fix a race between TpawAccountWidget and + GoaTpAccountLinker + +If TpawAccountWidget is used with a GtkDialog, the job completion +semantics are as follows: + + GtkDialog::response is emitted when the user clicks the Add button. + However, at this point the operation has just begun - the TpAccount + hasn't even been created. Once it is ready, TpawAccountWidget::close + (and a second GtkDialog::response) will be emitted. + +Apart from this, we need to track whether the corresponding GoaObject +has been created by GoaTpAccountLinker. + +We were quitting our hand rolled GMainLoop immediately after the +TpAccount / GoaObject pair were created without having anything to +wait for the TpawAccountWidget::close emission. This is wrong because +TpawAccountWidget does some follow-up work on the TpAccount after its +creation. Therefore, we were terminating add_account while some +asynchronous TpawAccountWidget operations could still be running. + +(Even though TpawAccountWidget holds a reference to itself during an +asynchronous operation, the destruction of the GtkDialog leads to +the widget being disposed.) + +Therefore, we track both the TpawAccountWidget::close emission and the +GoaObject creation. We quit the GMainLoop only after both events have +occured. + +https://bugzilla.gnome.org/show_bug.cgi?id=767299 +--- + src/goabackend/goatelepathyprovider.c | 27 ++++++++++++++++++++------- + 1 file changed, 20 insertions(+), 7 deletions(-) + +diff --git a/src/goabackend/goatelepathyprovider.c b/src/goabackend/goatelepathyprovider.c +index ff509cc501fe..7873607c1382 100644 +--- a/src/goabackend/goatelepathyprovider.c ++++ b/src/goabackend/goatelepathyprovider.c +@@ -275,6 +275,7 @@ typedef struct + GoaTelepathyProvider *provider; + GtkDialog *dialog; + GtkBox *vbox; ++ gboolean close_received; + + TpAccount *tp_account; + +@@ -282,6 +283,20 @@ typedef struct + guint goa_account_added_id; + } AddAccountData; + ++static void ++quit_main_loop_if_finished (AddAccountData *data) ++{ ++ if (data->ret != NULL && data->close_received) ++ g_main_loop_quit (data->loop); ++} ++ ++static void ++run_main_loop_if_needed (AddAccountData *data) ++{ ++ if (data->ret == NULL || !data->close_received) ++ g_main_loop_run (data->loop); ++} ++ + static gboolean + check_goa_object_match (AddAccountData *data, + GoaObject *goa_object) +@@ -311,7 +326,7 @@ check_goa_object_match (AddAccountData *data, + { + /* Found it! */ + data->ret = g_object_ref (goa_object); +- g_main_loop_quit (data->loop); ++ quit_main_loop_if_finished (data); + return TRUE; + } + +@@ -368,7 +383,8 @@ account_widget_close_cb (TpawAccountWidget *widget, + GtkResponseType response, + AddAccountData *data) + { +- gtk_dialog_response (data->dialog, response); ++ data->close_received = TRUE; ++ quit_main_loop_if_finished (data); + } + + static GoaObject * +@@ -442,11 +458,8 @@ add_account (GoaProvider *provider, + goto out; + } + +- if (data.ret == NULL) +- { +- /* We wait for the account to be created */ +- g_main_loop_run (data.loop); +- } ++ /* We wait for the account to be created */ ++ run_main_loop_if_needed (&data); + + out: + if (data.error != NULL) +-- +2.5.5 + + +From 3ed23bf6d26799486bf28749b2505c5b8d27a442 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Fri, 20 May 2016 19:50:08 +0200 +Subject: [PATCH 07/22] daemon: Style fix + +--- + src/daemon/goadaemon.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/daemon/goadaemon.c b/src/daemon/goadaemon.c +index 05ccb04c9ba5..c12030f2bbc2 100644 +--- a/src/daemon/goadaemon.c ++++ b/src/daemon/goadaemon.c +@@ -778,6 +778,8 @@ goa_daemon_reload_configuration (GoaDaemon *self) + g_list_free_full (key_files_to_free, (GDestroyNotify) g_key_file_free); + } + ++/* ---------------------------------------------------------------------------------------------------- */ ++ + static gchar * + generate_new_id (GoaDaemon *self) + { +-- +2.5.5 + + +From 8f57271140a7f7ee83b17bb88a4c0dd6fb70b214 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Mon, 11 May 2015 17:30:41 +0200 +Subject: [PATCH 08/22] provider: Use the name 'self' to refer to the instance + +--- + src/goabackend/goaprovider-priv.h | 24 +++--- + src/goabackend/goaprovider.c | 174 +++++++++++++++++++------------------- + src/goabackend/goaprovider.h | 32 +++---- + 3 files changed, 115 insertions(+), 115 deletions(-) + +diff --git a/src/goabackend/goaprovider-priv.h b/src/goabackend/goaprovider-priv.h +index dfede1b2bb97..bd110f8562a2 100644 +--- a/src/goabackend/goaprovider-priv.h ++++ b/src/goabackend/goaprovider-priv.h +@@ -1,6 +1,6 @@ + /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + /* +- * Copyright (C) 2013, 2014 Red Hat, Inc. ++ * Copyright (C) 2013, 2014, 2015 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -60,28 +60,28 @@ struct _GoaProviderClass + GObjectClass parent_class; + + /* pure virtual */ +- const gchar *(*get_provider_type) (GoaProvider *provider); +- gchar *(*get_provider_name) (GoaProvider *provider, ++ const gchar *(*get_provider_type) (GoaProvider *self); ++ gchar *(*get_provider_name) (GoaProvider *self, + GoaObject *object); +- GIcon *(*get_provider_icon) (GoaProvider *provider, ++ GIcon *(*get_provider_icon) (GoaProvider *self, + GoaObject *object); +- GoaObject *(*add_account) (GoaProvider *provider, ++ GoaObject *(*add_account) (GoaProvider *self, + GoaClient *client, + GtkDialog *dialog, + GtkBox *vbox, + GError **error); +- gboolean (*refresh_account) (GoaProvider *provider, ++ gboolean (*refresh_account) (GoaProvider *self, + GoaClient *client, + GoaObject *object, + GtkWindow *parent, + GError **error); +- void (*show_account) (GoaProvider *provider, ++ void (*show_account) (GoaProvider *self, + GoaClient *client, + GoaObject *object, + GtkBox *vbox, + GtkGrid *grid, + GtkGrid *dummy); +- gboolean (*build_object) (GoaProvider *provider, ++ gboolean (*build_object) (GoaProvider *self, + GoaObjectSkeleton *object, + GKeyFile *key_file, + const gchar *group, +@@ -89,16 +89,16 @@ struct _GoaProviderClass + gboolean just_added, + GError **error); + /* virtual but with default implementation */ +- gboolean (*ensure_credentials_sync) (GoaProvider *provider, ++ gboolean (*ensure_credentials_sync) (GoaProvider *self, + GoaObject *object, + gint *out_expires_in, + GCancellable *cancellable, + GError **error); +- guint (*get_credentials_generation) (GoaProvider *provider); ++ guint (*get_credentials_generation) (GoaProvider *self); + + /* pure virtual */ +- GoaProviderGroup (*get_provider_group) (GoaProvider *provider); +- GoaProviderFeatures (*get_provider_features) (GoaProvider *provider); ++ GoaProviderGroup (*get_provider_group) (GoaProvider *self); ++ GoaProviderFeatures (*get_provider_features) (GoaProvider *self); + + /*< private >*/ + /* Padding for future expansion */ +diff --git a/src/goabackend/goaprovider.c b/src/goabackend/goaprovider.c +index e6cac23d6adc..d0825a26f291 100644 +--- a/src/goabackend/goaprovider.c ++++ b/src/goabackend/goaprovider.c +@@ -1,6 +1,6 @@ + /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + /* +- * Copyright (C) 2011, 2012, 2013, 2014 Red Hat, Inc. ++ * Copyright (C) 2011, 2012, 2013, 2014, 2015 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -62,13 +62,13 @@ enum { + + static GParamSpec *properties[NUM_PROPERTIES] = { NULL, }; + +-static gboolean goa_provider_ensure_credentials_sync_real (GoaProvider *provider, ++static gboolean goa_provider_ensure_credentials_sync_real (GoaProvider *self, + GoaObject *object, + gint *out_expires_in, + GCancellable *cancellable, + GError **error); + +-static gboolean goa_provider_build_object_real (GoaProvider *provider, ++static gboolean goa_provider_build_object_real (GoaProvider *self, + GoaObjectSkeleton *object, + GKeyFile *key_file, + const gchar *group, +@@ -76,9 +76,9 @@ static gboolean goa_provider_build_object_real (GoaProvider *provider, + gboolean just_added, + GError **error); + +-static guint goa_provider_get_credentials_generation_real (GoaProvider *provider); ++static guint goa_provider_get_credentials_generation_real (GoaProvider *self); + +-static GIcon *goa_provider_get_provider_icon_default (GoaProvider *provider, ++static GIcon *goa_provider_get_provider_icon_default (GoaProvider *self, + GoaObject *object); + + #define GOA_PROVIDER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GOA_TYPE_PROVIDER, GoaProviderPrivate)) +@@ -124,17 +124,17 @@ goa_provider_set_property (GObject *object, + static void + goa_provider_dispose (GObject *object) + { +- GoaProvider *provider = GOA_PROVIDER (object); ++ GoaProvider *self = GOA_PROVIDER (object); + +- g_clear_pointer (&provider->priv->preseed_data, g_variant_unref); ++ g_clear_pointer (&self->priv->preseed_data, g_variant_unref); + + G_OBJECT_CLASS (goa_provider_parent_class)->dispose (object); + } + + static void +-goa_provider_init (GoaProvider *provider) ++goa_provider_init (GoaProvider *self) + { +- provider->priv = GOA_PROVIDER_GET_PRIVATE (provider); ++ self->priv = GOA_PROVIDER_GET_PRIVATE (self); + } + + static void +@@ -198,28 +198,28 @@ goa_provider_class_init (GoaProviderClass *klass) + + /** + * goa_provider_get_provider_type: +- * @provider: A #GoaProvider. ++ * @self: A #GoaProvider. + * +- * Gets the type of @provider. ++ * Gets the type of @self. + * + * This is a pure virtual method - a subclass must provide an + * implementation. + * +- * Returns: (transfer none): A string owned by @provider, do not free. ++ * Returns: (transfer none): A string owned by @self, do not free. + */ + const gchar * +-goa_provider_get_provider_type (GoaProvider *provider) ++goa_provider_get_provider_type (GoaProvider *self) + { +- g_return_val_if_fail (GOA_IS_PROVIDER (provider), NULL); +- return GOA_PROVIDER_GET_CLASS (provider)->get_provider_type (provider); ++ g_return_val_if_fail (GOA_IS_PROVIDER (self), NULL); ++ return GOA_PROVIDER_GET_CLASS (self)->get_provider_type (self); + } + + /** + * goa_provider_get_provider_name: +- * @provider: A #GoaProvider. ++ * @self: A #GoaProvider. + * @object: (allow-none): A #GoaObject for an account. + * +- * Gets a name for @provider and @object that is suitable for display ++ * Gets a name for @self and @object that is suitable for display + * in an user interface. The returned value may depend on @object (if + * it's not %NULL) - for example, hosted accounts might return a + * different name. +@@ -230,19 +230,19 @@ goa_provider_get_provider_type (GoaProvider *provider) + * Returns: (transfer full): A string that should be freed with g_free(). + */ + gchar * +-goa_provider_get_provider_name (GoaProvider *provider, ++goa_provider_get_provider_name (GoaProvider *self, + GoaObject *object) + { +- g_return_val_if_fail (GOA_IS_PROVIDER (provider), NULL); +- return GOA_PROVIDER_GET_CLASS (provider)->get_provider_name (provider, object); ++ g_return_val_if_fail (GOA_IS_PROVIDER (self), NULL); ++ return GOA_PROVIDER_GET_CLASS (self)->get_provider_name (self, object); + } + + /** + * goa_provider_get_provider_icon: +- * @provider: A #GoaProvider. ++ * @self: A #GoaProvider. + * @object: A #GoaObject for an account. + * +- * Gets an icon for @provider and @object that is suitable for display ++ * Gets an icon for @self and @object that is suitable for display + * in an user interface. The returned value may depend on @object - + * for example, hosted accounts might return a different icon. + * +@@ -254,20 +254,20 @@ goa_provider_get_provider_name (GoaProvider *provider, + * Returns: (transfer full): An icon that should be freed with g_object_unref(). + */ + GIcon * +-goa_provider_get_provider_icon (GoaProvider *provider, ++goa_provider_get_provider_icon (GoaProvider *self, + GoaObject *object) + { +- g_return_val_if_fail (GOA_IS_PROVIDER (provider), NULL); +- return GOA_PROVIDER_GET_CLASS (provider)->get_provider_icon (provider, object); ++ g_return_val_if_fail (GOA_IS_PROVIDER (self), NULL); ++ return GOA_PROVIDER_GET_CLASS (self)->get_provider_icon (self, object); + } + + static GIcon * +-goa_provider_get_provider_icon_default (GoaProvider *provider, ++goa_provider_get_provider_icon_default (GoaProvider *self, + GoaObject *object) + { + GIcon *ret; + gchar *s; +- s = g_strdup_printf ("goa-account-%s", goa_provider_get_provider_type (provider)); ++ s = g_strdup_printf ("goa-account-%s", goa_provider_get_provider_type (self)); + ret = g_themed_icon_new_with_default_fallbacks (s); + g_free (s); + return ret; +@@ -275,9 +275,9 @@ goa_provider_get_provider_icon_default (GoaProvider *provider, + + /** + * goa_provider_get_provider_group: +- * @provider: A #GoaProvider. ++ * @self: A #GoaProvider. + * +- * Gets the group to which @provider belongs that is suitable for ++ * Gets the group to which @self belongs that is suitable for + * organizing the providers while displaying them in an user + * interface. + * +@@ -291,15 +291,15 @@ goa_provider_get_provider_icon_default (GoaProvider *provider, + * Deprecated: 3.10: Use goa_provider_get_provider_features() instead. + */ + GoaProviderGroup +-goa_provider_get_provider_group (GoaProvider *provider) ++goa_provider_get_provider_group (GoaProvider *self) + { +- g_return_val_if_fail (GOA_IS_PROVIDER (provider), GOA_PROVIDER_GROUP_INVALID); +- return GOA_PROVIDER_GET_CLASS (provider)->get_provider_group (provider); ++ g_return_val_if_fail (GOA_IS_PROVIDER (self), GOA_PROVIDER_GROUP_INVALID); ++ return GOA_PROVIDER_GET_CLASS (self)->get_provider_group (self); + } + + /** + * goa_provider_get_provider_features: +- * @provider: A #GoaProvider. ++ * @self: A #GoaProvider. + * + * Get the features bitmask (eg. %GOA_PROVIDER_FEATURE_CHAT|%GOA_PROVIDER_FEATURE_CONTACTS) + * supported by the provider. +@@ -309,25 +309,25 @@ goa_provider_get_provider_group (GoaProvider *provider) + * Since: 3.10 + */ + GoaProviderFeatures +-goa_provider_get_provider_features (GoaProvider *provider) ++goa_provider_get_provider_features (GoaProvider *self) + { +- g_return_val_if_fail (GOA_IS_PROVIDER (provider), GOA_PROVIDER_FEATURE_INVALID); +- g_return_val_if_fail (GOA_PROVIDER_GET_CLASS (provider)->get_provider_features != NULL, GOA_PROVIDER_FEATURE_INVALID); +- return GOA_PROVIDER_GET_CLASS (provider)->get_provider_features (provider); ++ g_return_val_if_fail (GOA_IS_PROVIDER (self), GOA_PROVIDER_FEATURE_INVALID); ++ g_return_val_if_fail (GOA_PROVIDER_GET_CLASS (self)->get_provider_features != NULL, GOA_PROVIDER_FEATURE_INVALID); ++ return GOA_PROVIDER_GET_CLASS (self)->get_provider_features (self); + } + + /* ---------------------------------------------------------------------------------------------------- */ + + /** + * goa_provider_add_account: +- * @provider: A #GoaProvider. ++ * @self: A #GoaProvider. + * @client: A #GoaClient. + * @dialog: A #GtkDialog. + * @vbox: A vertically oriented #GtkBox to put content in. + * @error: Return location for error or %NULL. + * + * This method brings up the user interface necessary to create a new +- * account on @client of the type for @provider, interacts with the ++ * account on @client of the type for @self, interacts with the + * user to get all information needed and creates the account. + * + * The passed in @dialog widget is guaranteed to be visible with @vbox +@@ -358,7 +358,7 @@ goa_provider_get_provider_features (GoaProvider *provider) + * with g_object_unref()) or %NULL if @error is set. + */ + GoaObject * +-goa_provider_add_account (GoaProvider *provider, ++goa_provider_add_account (GoaProvider *self, + GoaClient *client, + GtkDialog *dialog, + GtkBox *vbox, +@@ -366,12 +366,12 @@ goa_provider_add_account (GoaProvider *provider, + { + GoaObject *ret; + +- g_return_val_if_fail (GOA_IS_PROVIDER (provider), NULL); ++ g_return_val_if_fail (GOA_IS_PROVIDER (self), NULL); + g_return_val_if_fail (GOA_IS_CLIENT (client), NULL); + g_return_val_if_fail (GTK_IS_DIALOG (dialog), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + +- ret = GOA_PROVIDER_GET_CLASS (provider)->add_account (provider, client, dialog, vbox, error); ++ ret = GOA_PROVIDER_GET_CLASS (self)->add_account (self, client, dialog, vbox, error); + + g_warn_if_fail ((ret == NULL && (error == NULL || *error != NULL)) || GOA_IS_OBJECT (ret)); + +@@ -382,7 +382,7 @@ goa_provider_add_account (GoaProvider *provider, + + /** + * goa_provider_refresh_account: +- * @provider: A #GoaProvider. ++ * @self: A #GoaProvider. + * @client: A #GoaClient. + * @object: A #GoaObject with a #GoaAccount interface. + * @parent: (allow-none): Transient parent of dialogs or %NULL. +@@ -406,26 +406,26 @@ goa_provider_add_account (GoaProvider *provider, + * is set. + */ + gboolean +-goa_provider_refresh_account (GoaProvider *provider, ++goa_provider_refresh_account (GoaProvider *self, + GoaClient *client, + GoaObject *object, + GtkWindow *parent, + GError **error) + { +- g_return_val_if_fail (GOA_IS_PROVIDER (provider), FALSE); ++ g_return_val_if_fail (GOA_IS_PROVIDER (self), FALSE); + g_return_val_if_fail (GOA_IS_CLIENT (client), FALSE); + g_return_val_if_fail (GOA_IS_OBJECT (object) && goa_object_peek_account (object) != NULL, FALSE); + g_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + +- return GOA_PROVIDER_GET_CLASS (provider)->refresh_account (provider, client, object, parent, error); ++ return GOA_PROVIDER_GET_CLASS (self)->refresh_account (self, client, object, parent, error); + } + + /* ---------------------------------------------------------------------------------------------------- */ + + /** + * goa_provider_show_account: +- * @provider: A #GoaProvider. ++ * @self: A #GoaProvider. + * @client: A #GoaClient. + * @object: A #GoaObject with a #GoaAccount interface. + * @vbox: A vertically oriented #GtkBox to put content in. +@@ -439,27 +439,27 @@ goa_provider_refresh_account (GoaProvider *provider, + * implementation. + */ + void +-goa_provider_show_account (GoaProvider *provider, ++goa_provider_show_account (GoaProvider *self, + GoaClient *client, + GoaObject *object, + GtkBox *vbox, + GtkGrid *grid, + GtkGrid *dummy) + { +- g_return_if_fail (GOA_IS_PROVIDER (provider)); ++ g_return_if_fail (GOA_IS_PROVIDER (self)); + g_return_if_fail (GOA_IS_CLIENT (client)); + g_return_if_fail (GOA_IS_OBJECT (object) && goa_object_peek_account (object) != NULL); + g_return_if_fail (GTK_IS_BOX (vbox)); + g_return_if_fail (GTK_IS_GRID (grid)); + +- GOA_PROVIDER_GET_CLASS (provider)->show_account (provider, client, object, vbox, grid, dummy); ++ GOA_PROVIDER_GET_CLASS (self)->show_account (self, client, object, vbox, grid, dummy); + } + + /* ---------------------------------------------------------------------------------------------------- */ + + /** + * goa_provider_build_object: +- * @provider: A #GoaProvider. ++ * @self: A #GoaProvider. + * @object: The #GoaObjectSkeleton that is being built. + * @key_file: The #GKeyFile with configuation data. + * @group: The group in @key_file to get data from. +@@ -484,7 +484,7 @@ goa_provider_show_account (GoaProvider *provider, + * Returns: %TRUE if data was valid, %FALSE if @error is set. + */ + gboolean +-goa_provider_build_object (GoaProvider *provider, ++goa_provider_build_object (GoaProvider *self, + GoaObjectSkeleton *object, + GKeyFile *key_file, + const gchar *group, +@@ -492,19 +492,19 @@ goa_provider_build_object (GoaProvider *provider, + gboolean just_added, + GError **error) + { +- g_return_val_if_fail (GOA_IS_PROVIDER (provider), FALSE); ++ g_return_val_if_fail (GOA_IS_PROVIDER (self), FALSE); + g_return_val_if_fail (GOA_IS_OBJECT_SKELETON (object) && goa_object_peek_account (GOA_OBJECT (object)) != NULL, FALSE); + g_return_val_if_fail (key_file != NULL, FALSE); + g_return_val_if_fail (group != NULL, FALSE); + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); +- return GOA_PROVIDER_GET_CLASS (provider)->build_object (provider, +- object, +- key_file, +- group, +- connection, +- just_added, +- error); ++ return GOA_PROVIDER_GET_CLASS (self)->build_object (self, ++ object, ++ key_file, ++ group, ++ connection, ++ just_added, ++ error); + } + + /* ---------------------------------------------------------------------------------------------------- */ +@@ -553,7 +553,7 @@ ensure_credentials_in_thread_func (GSimpleAsyncResult *simple, + + /** + * goa_provider_ensure_credentials: +- * @provider: A #GoaProvider. ++ * @self: A #GoaProvider. + * @object: A #GoaObject with a #GoaAccount interface. + * @cancellable: (allow-none): A #GCancellable or %NULL. + * @callback: The function to call when the request is satisfied. +@@ -572,7 +572,7 @@ ensure_credentials_in_thread_func (GSimpleAsyncResult *simple, + * another implementation. + */ + void +-goa_provider_ensure_credentials (GoaProvider *provider, ++goa_provider_ensure_credentials (GoaProvider *self, + GoaObject *object, + GCancellable *cancellable, + GAsyncReadyCallback callback, +@@ -580,11 +580,11 @@ goa_provider_ensure_credentials (GoaProvider *provider, + { + GSimpleAsyncResult *simple; + +- g_return_if_fail (GOA_IS_PROVIDER (provider)); ++ g_return_if_fail (GOA_IS_PROVIDER (self)); + g_return_if_fail (GOA_IS_OBJECT (object)); + g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + +- simple = g_simple_async_result_new (G_OBJECT (provider), ++ simple = g_simple_async_result_new (G_OBJECT (self), + callback, + user_data, + goa_provider_ensure_credentials); +@@ -600,7 +600,7 @@ goa_provider_ensure_credentials (GoaProvider *provider, + + /** + * goa_provider_ensure_credentials_finish: +- * @provider: A #GoaProvider. ++ * @self: A #GoaProvider. + * @out_expires_in: (out): Return location for how long the expired credentials are good for (0 if unknown) or %NULL. + * @res: A #GAsyncResult obtained from the #GAsyncReadyCallback passed to goa_provider_ensure_credentials(). + * @error: Return location for error or %NULL. +@@ -610,7 +610,7 @@ goa_provider_ensure_credentials (GoaProvider *provider, + * Returns: %TRUE if the credentials for the passed #GoaObject are valid, %FALSE if @error is set. + */ + gboolean +-goa_provider_ensure_credentials_finish (GoaProvider *provider, ++goa_provider_ensure_credentials_finish (GoaProvider *self, + gint *out_expires_in, + GAsyncResult *res, + GError **error) +@@ -621,7 +621,7 @@ goa_provider_ensure_credentials_finish (GoaProvider *provider, + + ret = FALSE; + +- g_return_val_if_fail (GOA_IS_PROVIDER (provider), FALSE); ++ g_return_val_if_fail (GOA_IS_PROVIDER (self), FALSE); + g_return_val_if_fail (G_IS_ASYNC_RESULT (res), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + +@@ -643,7 +643,7 @@ goa_provider_ensure_credentials_finish (GoaProvider *provider, + + /** + * goa_provider_ensure_credentials_sync: +- * @provider: A #GoaProvider. ++ * @self: A #GoaProvider. + * @object: A #GoaObject with a #GoaAccount interface. + * @out_expires_in: (out): Return location for how long the expired credentials are good for (0 if unknown) or %NULL. + * @cancellable: (allow-none): A #GCancellable or %NULL. +@@ -655,22 +655,22 @@ goa_provider_ensure_credentials_finish (GoaProvider *provider, + * Returns: %TRUE if the credentials for the passed #GoaObject are valid, %FALSE if @error is set. + */ + gboolean +-goa_provider_ensure_credentials_sync (GoaProvider *provider, ++goa_provider_ensure_credentials_sync (GoaProvider *self, + GoaObject *object, + gint *out_expires_in, + GCancellable *cancellable, + GError **error) + { +- g_return_val_if_fail (GOA_IS_PROVIDER (provider), FALSE); ++ g_return_val_if_fail (GOA_IS_PROVIDER (self), FALSE); + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); +- return GOA_PROVIDER_GET_CLASS (provider)->ensure_credentials_sync (provider, object, out_expires_in, cancellable, error); ++ return GOA_PROVIDER_GET_CLASS (self)->ensure_credentials_sync (self, object, out_expires_in, cancellable, error); + } + + /* ---------------------------------------------------------------------------------------------------- */ + + static gboolean +-goa_provider_ensure_credentials_sync_real (GoaProvider *provider, ++goa_provider_ensure_credentials_sync_real (GoaProvider *self, + GoaObject *object, + gint *out_expires_in, + GCancellable *cancellable, +@@ -680,12 +680,12 @@ goa_provider_ensure_credentials_sync_real (GoaProvider *provider, + GOA_ERROR, + GOA_ERROR_NOT_SUPPORTED, + _("ensure_credentials_sync is not implemented on type %s"), +- g_type_name (G_TYPE_FROM_INSTANCE (provider))); ++ g_type_name (G_TYPE_FROM_INSTANCE (self))); + return FALSE; + } + + static gboolean +-goa_provider_build_object_real (GoaProvider *provider, ++goa_provider_build_object_real (GoaProvider *self, + GoaObjectSkeleton *object, + GKeyFile *key_file, + const gchar *group, +@@ -701,7 +701,7 @@ goa_provider_build_object_real (GoaProvider *provider, + + /** + * goa_provider_get_credentials_generation: +- * @provider: A #GoaProvider. ++ * @self: A #GoaProvider. + * + * Gets the generation of credentials being used for the provider. + * +@@ -719,14 +719,14 @@ goa_provider_build_object_real (GoaProvider *provider, + * Returns: The current generation of credentials. + */ + guint +-goa_provider_get_credentials_generation (GoaProvider *provider) ++goa_provider_get_credentials_generation (GoaProvider *self) + { +- g_return_val_if_fail (GOA_IS_PROVIDER (provider), 0); +- return GOA_PROVIDER_GET_CLASS (provider)->get_credentials_generation (provider); ++ g_return_val_if_fail (GOA_IS_PROVIDER (self), 0); ++ return GOA_PROVIDER_GET_CLASS (self)->get_credentials_generation (self); + } + + static guint +-goa_provider_get_credentials_generation_real (GoaProvider *provider) ++goa_provider_get_credentials_generation_real (GoaProvider *self) + { + return 0; + } +@@ -1122,7 +1122,7 @@ goa_provider_get_all_finish (GList **out_providers, + + /** + * goa_provider_set_preseed_data: +- * @provider: The #GoaProvider ++ * @self: The #GoaProvider + * @preseed_data: A #GVariant of type a{sv} + * + * Sets the #GoaProvider:preseed-data property to feed any information already +@@ -1132,18 +1132,18 @@ goa_provider_get_all_finish (GList **out_providers, + * 'inline' use of the g_variant_new() family of functions. + */ + void +-goa_provider_set_preseed_data (GoaProvider *provider, ++goa_provider_set_preseed_data (GoaProvider *self, + GVariant *preseed_data) + { +- g_clear_pointer (&provider->priv->preseed_data, g_variant_unref); ++ g_clear_pointer (&self->priv->preseed_data, g_variant_unref); + if (preseed_data != NULL) +- provider->priv->preseed_data = g_variant_ref_sink (preseed_data); +- g_object_notify (G_OBJECT (provider), "preseed-data"); ++ self->priv->preseed_data = g_variant_ref_sink (preseed_data); ++ g_object_notify (G_OBJECT (self), "preseed-data"); + } + + /** + * goa_provider_get_preseed_data: +- * @provider: The #GoaProvider ++ * @self: The #GoaProvider + * + * Gets the #GVariant set through the #GoaProvider:preseed-data property. + * +@@ -1151,9 +1151,9 @@ goa_provider_set_preseed_data (GoaProvider *provider, + * the property is overridden or the provider freed. + */ + GVariant * +-goa_provider_get_preseed_data (GoaProvider *provider) ++goa_provider_get_preseed_data (GoaProvider *self) + { +- return provider->priv->preseed_data; ++ return self->priv->preseed_data; + } + + /* ---------------------------------------------------------------------------------------------------- */ +diff --git a/src/goabackend/goaprovider.h b/src/goabackend/goaprovider.h +index d67c0c8742b6..3c18d92d0fdc 100644 +--- a/src/goabackend/goaprovider.h ++++ b/src/goabackend/goaprovider.h +@@ -1,6 +1,6 @@ + /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + /* +- * Copyright (C) 2011, 2012 Red Hat, Inc. ++ * Copyright (C) 2011, 2012, 2015 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -39,55 +39,55 @@ typedef struct _GoaProviderClass GoaProviderClass; + typedef struct _GoaProviderPrivate GoaProviderPrivate; + + GType goa_provider_get_type (void) G_GNUC_CONST; +-const gchar *goa_provider_get_provider_type (GoaProvider *provider); +-gchar *goa_provider_get_provider_name (GoaProvider *provider, ++const gchar *goa_provider_get_provider_type (GoaProvider *self); ++gchar *goa_provider_get_provider_name (GoaProvider *self, + GoaObject *object); +-GIcon *goa_provider_get_provider_icon (GoaProvider *provider, ++GIcon *goa_provider_get_provider_icon (GoaProvider *self, + GoaObject *object); + G_DEPRECATED_FOR(goa_provider_get_provider_features) +-GoaProviderGroup goa_provider_get_provider_group (GoaProvider *provider); +-GoaProviderFeatures goa_provider_get_provider_features (GoaProvider *provider); +-void goa_provider_set_preseed_data (GoaProvider *provider, ++GoaProviderGroup goa_provider_get_provider_group (GoaProvider *self); ++GoaProviderFeatures goa_provider_get_provider_features (GoaProvider *self); ++void goa_provider_set_preseed_data (GoaProvider *self, + GVariant *preseed_data); +-GVariant *goa_provider_get_preseed_data (GoaProvider *provider); +-GoaObject *goa_provider_add_account (GoaProvider *provider, ++GVariant *goa_provider_get_preseed_data (GoaProvider *self); ++GoaObject *goa_provider_add_account (GoaProvider *self, + GoaClient *client, + GtkDialog *dialog, + GtkBox *vbox, + GError **error); +-gboolean goa_provider_refresh_account (GoaProvider *provider, ++gboolean goa_provider_refresh_account (GoaProvider *self, + GoaClient *client, + GoaObject *object, + GtkWindow *parent, + GError **error); +-void goa_provider_show_account (GoaProvider *provider, ++void goa_provider_show_account (GoaProvider *self, + GoaClient *client, + GoaObject *object, + GtkBox *vbox, + GtkGrid *grid, + GtkGrid *dummy); +-gboolean goa_provider_build_object (GoaProvider *provider, ++gboolean goa_provider_build_object (GoaProvider *self, + GoaObjectSkeleton *object, + GKeyFile *key_file, + const gchar *group, + GDBusConnection *connection, + gboolean just_added, + GError **error); +-void goa_provider_ensure_credentials (GoaProvider *provider, ++void goa_provider_ensure_credentials (GoaProvider *self, + GoaObject *object, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +-gboolean goa_provider_ensure_credentials_finish (GoaProvider *provider, ++gboolean goa_provider_ensure_credentials_finish (GoaProvider *self, + gint *out_expires_in, + GAsyncResult *res, + GError **error); +-gboolean goa_provider_ensure_credentials_sync (GoaProvider *provider, ++gboolean goa_provider_ensure_credentials_sync (GoaProvider *self, + GoaObject *object, + gint *out_expires_in, + GCancellable *cancellable, + GError **error); +-guint goa_provider_get_credentials_generation (GoaProvider *provider); ++guint goa_provider_get_credentials_generation (GoaProvider *self); + + void goa_provider_get_all (GAsyncReadyCallback callback, + gpointer user_data); +-- +2.5.5 + + +From 6fe5f6848883e8f147d34071d306887fd5b548d5 Mon Sep 17 00:00:00 2001 +From: Christophe Fergeau +Date: Thu, 30 Jul 2015 22:33:34 +0200 +Subject: [PATCH 09/22] Reorder GoaProviderClass fields as it's private now + +We can group all pure virtual functions together, and drop the structure +padding as GoaProvider is not publicly exposed anymore. + +https://bugzilla.gnome.org/show_bug.cgi?id=752941 +--- + src/goabackend/goaprovider-priv.h | 11 +++-------- + 1 file changed, 3 insertions(+), 8 deletions(-) + +diff --git a/src/goabackend/goaprovider-priv.h b/src/goabackend/goaprovider-priv.h +index bd110f8562a2..f887b53a7276 100644 +--- a/src/goabackend/goaprovider-priv.h ++++ b/src/goabackend/goaprovider-priv.h +@@ -88,6 +88,9 @@ struct _GoaProviderClass + GDBusConnection *connection, + gboolean just_added, + GError **error); ++ GoaProviderGroup (*get_provider_group) (GoaProvider *self); ++ GoaProviderFeatures (*get_provider_features) (GoaProvider *self); ++ + /* virtual but with default implementation */ + gboolean (*ensure_credentials_sync) (GoaProvider *self, + GoaObject *object, +@@ -95,14 +98,6 @@ struct _GoaProviderClass + GCancellable *cancellable, + GError **error); + guint (*get_credentials_generation) (GoaProvider *self); +- +- /* pure virtual */ +- GoaProviderGroup (*get_provider_group) (GoaProvider *self); +- GoaProviderFeatures (*get_provider_features) (GoaProvider *self); +- +- /*< private >*/ +- /* Padding for future expansion */ +- gpointer goa_reserved[31]; + }; + + /** +-- +2.5.5 + + +From b858e2f79292cdd888b0357c5442096bacd84d89 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Fri, 20 May 2016 17:12:38 +0200 +Subject: [PATCH 10/22] provider: Re-order and re-align the GoaProviderClass + members + +We don't allow out-of-tree providers and GoaProviderClass is not part +of the exported ABI. + +https://bugzilla.gnome.org/show_bug.cgi?id=766733 +--- + src/goabackend/goaprovider-priv.h | 72 +++++++++++++++++++-------------------- + 1 file changed, 36 insertions(+), 36 deletions(-) + +diff --git a/src/goabackend/goaprovider-priv.h b/src/goabackend/goaprovider-priv.h +index f887b53a7276..0dedfd1ce600 100644 +--- a/src/goabackend/goaprovider-priv.h ++++ b/src/goabackend/goaprovider-priv.h +@@ -60,44 +60,44 @@ struct _GoaProviderClass + GObjectClass parent_class; + + /* pure virtual */ +- const gchar *(*get_provider_type) (GoaProvider *self); +- gchar *(*get_provider_name) (GoaProvider *self, +- GoaObject *object); +- GIcon *(*get_provider_icon) (GoaProvider *self, +- GoaObject *object); +- GoaObject *(*add_account) (GoaProvider *self, +- GoaClient *client, +- GtkDialog *dialog, +- GtkBox *vbox, +- GError **error); +- gboolean (*refresh_account) (GoaProvider *self, +- GoaClient *client, +- GoaObject *object, +- GtkWindow *parent, +- GError **error); +- void (*show_account) (GoaProvider *self, +- GoaClient *client, +- GoaObject *object, +- GtkBox *vbox, +- GtkGrid *grid, +- GtkGrid *dummy); +- gboolean (*build_object) (GoaProvider *self, +- GoaObjectSkeleton *object, +- GKeyFile *key_file, +- const gchar *group, +- GDBusConnection *connection, +- gboolean just_added, +- GError **error); +- GoaProviderGroup (*get_provider_group) (GoaProvider *self); +- GoaProviderFeatures (*get_provider_features) (GoaProvider *self); ++ GoaObject *(*add_account) (GoaProvider *self, ++ GoaClient *client, ++ GtkDialog *dialog, ++ GtkBox *vbox, ++ GError **error); ++ GoaProviderFeatures (*get_provider_features) (GoaProvider *self); ++ GoaProviderGroup (*get_provider_group) (GoaProvider *self); ++ gchar *(*get_provider_name) (GoaProvider *self, ++ GoaObject *object); ++ const gchar *(*get_provider_type) (GoaProvider *self); ++ gboolean (*refresh_account) (GoaProvider *self, ++ GoaClient *client, ++ GoaObject *object, ++ GtkWindow *parent, ++ GError **error); ++ void (*show_account) (GoaProvider *self, ++ GoaClient *client, ++ GoaObject *object, ++ GtkBox *vbox, ++ GtkGrid *grid, ++ GtkGrid *dummy); + + /* virtual but with default implementation */ +- gboolean (*ensure_credentials_sync) (GoaProvider *self, +- GoaObject *object, +- gint *out_expires_in, +- GCancellable *cancellable, +- GError **error); +- guint (*get_credentials_generation) (GoaProvider *self); ++ gboolean (*build_object) (GoaProvider *self, ++ GoaObjectSkeleton *object, ++ GKeyFile *key_file, ++ const gchar *group, ++ GDBusConnection *connection, ++ gboolean just_added, ++ GError **error); ++ gboolean (*ensure_credentials_sync) (GoaProvider *self, ++ GoaObject *object, ++ gint *out_expires_in, ++ GCancellable *cancellable, ++ GError **error); ++ guint (*get_credentials_generation) (GoaProvider *self); ++ GIcon *(*get_provider_icon) (GoaProvider *self, ++ GoaObject *object); + }; + + /** +-- +2.5.5 + + +From 16a8abc3e657eabcebae6d04f5309bd6994d36e4 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Fri, 20 May 2016 18:42:01 +0200 +Subject: [PATCH 11/22] provider: Re-align the function prototypes + +https://bugzilla.gnome.org/show_bug.cgi?id=766733 +--- + src/goabackend/goaprovider-priv.h | 4 +- + src/goabackend/goaprovider.h | 130 +++++++++++++++++++++----------------- + 2 files changed, 75 insertions(+), 59 deletions(-) + +diff --git a/src/goabackend/goaprovider-priv.h b/src/goabackend/goaprovider-priv.h +index 0dedfd1ce600..06bed8c0308e 100644 +--- a/src/goabackend/goaprovider-priv.h ++++ b/src/goabackend/goaprovider-priv.h +@@ -114,9 +114,9 @@ struct _GoaProviderClass + */ + #define GOA_PROVIDER_FACTORY_EXTENSION_POINT_NAME "goa-backend-provider-factory" + +-void goa_provider_ensure_builtins_loaded (void); ++void goa_provider_ensure_builtins_loaded (void); + +-void goa_provider_ensure_extension_points_registered (void); ++void goa_provider_ensure_extension_points_registered (void); + + G_END_DECLS + +diff --git a/src/goabackend/goaprovider.h b/src/goabackend/goaprovider.h +index 3c18d92d0fdc..1a59fbe80107 100644 +--- a/src/goabackend/goaprovider.h ++++ b/src/goabackend/goaprovider.h +@@ -38,64 +38,80 @@ G_BEGIN_DECLS + typedef struct _GoaProviderClass GoaProviderClass; + typedef struct _GoaProviderPrivate GoaProviderPrivate; + +-GType goa_provider_get_type (void) G_GNUC_CONST; +-const gchar *goa_provider_get_provider_type (GoaProvider *self); +-gchar *goa_provider_get_provider_name (GoaProvider *self, +- GoaObject *object); +-GIcon *goa_provider_get_provider_icon (GoaProvider *self, +- GoaObject *object); ++GType goa_provider_get_type (void) G_GNUC_CONST; ++ ++const gchar *goa_provider_get_provider_type (GoaProvider *self); ++ ++gchar *goa_provider_get_provider_name (GoaProvider *self, ++ GoaObject *object); ++ ++GIcon *goa_provider_get_provider_icon (GoaProvider *self, ++ GoaObject *object); ++ + G_DEPRECATED_FOR(goa_provider_get_provider_features) +-GoaProviderGroup goa_provider_get_provider_group (GoaProvider *self); +-GoaProviderFeatures goa_provider_get_provider_features (GoaProvider *self); +-void goa_provider_set_preseed_data (GoaProvider *self, +- GVariant *preseed_data); +-GVariant *goa_provider_get_preseed_data (GoaProvider *self); +-GoaObject *goa_provider_add_account (GoaProvider *self, +- GoaClient *client, +- GtkDialog *dialog, +- GtkBox *vbox, +- GError **error); +-gboolean goa_provider_refresh_account (GoaProvider *self, +- GoaClient *client, +- GoaObject *object, +- GtkWindow *parent, +- GError **error); +-void goa_provider_show_account (GoaProvider *self, +- GoaClient *client, +- GoaObject *object, +- GtkBox *vbox, +- GtkGrid *grid, +- GtkGrid *dummy); +-gboolean goa_provider_build_object (GoaProvider *self, +- GoaObjectSkeleton *object, +- GKeyFile *key_file, +- const gchar *group, +- GDBusConnection *connection, +- gboolean just_added, +- GError **error); +-void goa_provider_ensure_credentials (GoaProvider *self, +- GoaObject *object, +- GCancellable *cancellable, +- GAsyncReadyCallback callback, +- gpointer user_data); +-gboolean goa_provider_ensure_credentials_finish (GoaProvider *self, +- gint *out_expires_in, +- GAsyncResult *res, +- GError **error); +-gboolean goa_provider_ensure_credentials_sync (GoaProvider *self, +- GoaObject *object, +- gint *out_expires_in, +- GCancellable *cancellable, +- GError **error); +-guint goa_provider_get_credentials_generation (GoaProvider *self); +- +-void goa_provider_get_all (GAsyncReadyCallback callback, +- gpointer user_data); +-gboolean goa_provider_get_all_finish (GList **out_providers, +- GAsyncResult *result, +- GError **error); +- +-GoaProvider *goa_provider_get_for_provider_type (const gchar *provider_type); ++GoaProviderGroup goa_provider_get_provider_group (GoaProvider *self); ++ ++GoaProviderFeatures goa_provider_get_provider_features (GoaProvider *self); ++ ++void goa_provider_set_preseed_data (GoaProvider *self, ++ GVariant *preseed_data); ++ ++GVariant *goa_provider_get_preseed_data (GoaProvider *self); ++ ++GoaObject *goa_provider_add_account (GoaProvider *self, ++ GoaClient *client, ++ GtkDialog *dialog, ++ GtkBox *vbox, ++ GError **error); ++ ++gboolean goa_provider_refresh_account (GoaProvider *self, ++ GoaClient *client, ++ GoaObject *object, ++ GtkWindow *parent, ++ GError **error); ++ ++void goa_provider_show_account (GoaProvider *self, ++ GoaClient *client, ++ GoaObject *object, ++ GtkBox *vbox, ++ GtkGrid *grid, ++ GtkGrid *dummy); ++ ++gboolean goa_provider_build_object (GoaProvider *self, ++ GoaObjectSkeleton *object, ++ GKeyFile *key_file, ++ const gchar *group, ++ GDBusConnection *connection, ++ gboolean just_added, ++ GError **error); ++ ++void goa_provider_ensure_credentials (GoaProvider *self, ++ GoaObject *object, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data); ++ ++gboolean goa_provider_ensure_credentials_finish (GoaProvider *self, ++ gint *out_expires_in, ++ GAsyncResult *res, ++ GError **error); ++ ++gboolean goa_provider_ensure_credentials_sync (GoaProvider *self, ++ GoaObject *object, ++ gint *out_expires_in, ++ GCancellable *cancellable, ++ GError **error); ++ ++guint goa_provider_get_credentials_generation (GoaProvider *self); ++ ++void goa_provider_get_all (GAsyncReadyCallback callback, ++ gpointer user_data); ++ ++gboolean goa_provider_get_all_finish (GList **out_providers, ++ GAsyncResult *result, ++ GError **error); ++ ++GoaProvider *goa_provider_get_for_provider_type (const gchar *provider_type); + + /* ---------------------------------------------------------------------------------------------------- */ + +-- +2.5.5 + + +From ff49fe3e5d7d03696edcb0e411ea167bccb8aa8b Mon Sep 17 00:00:00 2001 +From: Christophe Fergeau +Date: Sat, 2 May 2015 00:07:20 +0200 +Subject: [PATCH 12/22] provider: Unify default vfunc name + +The default vfunc implementations in GoaProvider are named _real except +for goa_provider_get_provider_icon_default(). +This commit changes the "_default" suffix to "_real" for better +consistency. + +https://bugzilla.gnome.org/show_bug.cgi?id=752941 +--- + src/goabackend/goaprovider.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/src/goabackend/goaprovider.c b/src/goabackend/goaprovider.c +index d0825a26f291..3a2d61408357 100644 +--- a/src/goabackend/goaprovider.c ++++ b/src/goabackend/goaprovider.c +@@ -78,8 +78,8 @@ static gboolean goa_provider_build_object_real (GoaProvider *self, + + static guint goa_provider_get_credentials_generation_real (GoaProvider *self); + +-static GIcon *goa_provider_get_provider_icon_default (GoaProvider *self, +- GoaObject *object); ++static GIcon *goa_provider_get_provider_icon_real (GoaProvider *self, ++ GoaObject *object); + + #define GOA_PROVIDER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GOA_TYPE_PROVIDER, GoaProviderPrivate)) + +@@ -151,7 +151,7 @@ goa_provider_class_init (GoaProviderClass *klass) + klass->build_object = goa_provider_build_object_real; + klass->ensure_credentials_sync = goa_provider_ensure_credentials_sync_real; + klass->get_credentials_generation = goa_provider_get_credentials_generation_real; +- klass->get_provider_icon = goa_provider_get_provider_icon_default; ++ klass->get_provider_icon = goa_provider_get_provider_icon_real; + + /** + * GoaProvider:preseed-data +@@ -262,8 +262,8 @@ goa_provider_get_provider_icon (GoaProvider *self, + } + + static GIcon * +-goa_provider_get_provider_icon_default (GoaProvider *self, +- GoaObject *object) ++goa_provider_get_provider_icon_real (GoaProvider *self, ++ GoaObject *object) + { + GIcon *ret; + gchar *s; +-- +2.5.5 + + +From 13d27c80e5883191984b719c69210411af423e9d Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Fri, 20 May 2016 18:48:37 +0200 +Subject: [PATCH 13/22] provider: Add a new vfunc for backend-specific work on + account removal + +Some GoaProvider sub-classes (eg., Kerberos and Telepathy) need to +perform some extra clean up when an account is removed. This virtual +method will let them hook into the account removal operation to do so. + +The default implementation of this virtual method simply returns TRUE. + +https://bugzilla.gnome.org/show_bug.cgi?id=766733 +--- + src/goabackend/goaprovider-priv.h | 18 ++++++++++ + src/goabackend/goaprovider.c | 72 +++++++++++++++++++++++++++++++++++++++ + 2 files changed, 90 insertions(+) + +diff --git a/src/goabackend/goaprovider-priv.h b/src/goabackend/goaprovider-priv.h +index 06bed8c0308e..762989158807 100644 +--- a/src/goabackend/goaprovider-priv.h ++++ b/src/goabackend/goaprovider-priv.h +@@ -98,6 +98,14 @@ struct _GoaProviderClass + guint (*get_credentials_generation) (GoaProvider *self); + GIcon *(*get_provider_icon) (GoaProvider *self, + GoaObject *object); ++ void (*remove_account) (GoaProvider *self, ++ GoaObject *object, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data); ++ gboolean (*remove_account_finish) (GoaProvider *self, ++ GAsyncResult *res, ++ GError **error); + }; + + /** +@@ -118,6 +126,16 @@ void goa_provider_ensure_builtins_loaded (void); + + void goa_provider_ensure_extension_points_registered (void); + ++void goa_provider_remove_account (GoaProvider *self, ++ GoaObject *object, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data); ++ ++gboolean goa_provider_remove_account_finish (GoaProvider *self, ++ GAsyncResult *res, ++ GError **error); ++ + G_END_DECLS + + #endif /* __GOA_PROVIDER_PRIV_H__ */ +diff --git a/src/goabackend/goaprovider.c b/src/goabackend/goaprovider.c +index 3a2d61408357..174fe9ac67be 100644 +--- a/src/goabackend/goaprovider.c ++++ b/src/goabackend/goaprovider.c +@@ -81,6 +81,16 @@ static guint goa_provider_get_credentials_generation_real (GoaProvider *self); + static GIcon *goa_provider_get_provider_icon_real (GoaProvider *self, + GoaObject *object); + ++static void goa_provider_remove_account_real (GoaProvider *self, ++ GoaObject *object, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data); ++ ++static gboolean goa_provider_remove_account_finish_real (GoaProvider *self, ++ GAsyncResult *res, ++ GError **error); ++ + #define GOA_PROVIDER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GOA_TYPE_PROVIDER, GoaProviderPrivate)) + + G_DEFINE_ABSTRACT_TYPE (GoaProvider, goa_provider, G_TYPE_OBJECT); +@@ -152,6 +162,8 @@ goa_provider_class_init (GoaProviderClass *klass) + klass->ensure_credentials_sync = goa_provider_ensure_credentials_sync_real; + klass->get_credentials_generation = goa_provider_get_credentials_generation_real; + klass->get_provider_icon = goa_provider_get_provider_icon_real; ++ klass->remove_account = goa_provider_remove_account_real; ++ klass->remove_account_finish = goa_provider_remove_account_finish_real; + + /** + * GoaProvider:preseed-data +@@ -1120,6 +1132,66 @@ goa_provider_get_all_finish (GList **out_providers, + + /* ---------------------------------------------------------------------------------------------------- */ + ++void ++goa_provider_remove_account (GoaProvider *self, ++ GoaObject *object, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data) ++{ ++ g_return_if_fail (GOA_IS_PROVIDER (self)); ++ g_return_if_fail (GOA_IS_OBJECT (object)); ++ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); ++ ++ GOA_PROVIDER_GET_CLASS (self)->remove_account (self, object, cancellable, callback, user_data); ++} ++ ++gboolean ++goa_provider_remove_account_finish (GoaProvider *self, ++ GAsyncResult *res, ++ GError **error) ++{ ++ g_return_val_if_fail (GOA_IS_PROVIDER (self), FALSE); ++ g_return_val_if_fail (G_IS_ASYNC_RESULT (res), FALSE); ++ g_return_val_if_fail (error == NULL || *error == NULL, FALSE); ++ ++ return GOA_PROVIDER_GET_CLASS (self)->remove_account_finish (self, res, error); ++} ++ ++/* ---------------------------------------------------------------------------------------------------- */ ++ ++static void ++goa_provider_remove_account_real (GoaProvider *self, ++ GoaObject *object, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data) ++{ ++ GTask *task; ++ ++ task = g_task_new (self, cancellable, callback, user_data); ++ g_task_set_source_tag (task, goa_provider_remove_account_real); ++ g_task_return_boolean (task, TRUE); ++ g_object_unref (task); ++} ++ ++static gboolean ++goa_provider_remove_account_finish_real (GoaProvider *self, ++ GAsyncResult *res, ++ GError **error) ++{ ++ GTask *task; ++ ++ g_return_val_if_fail (g_task_is_valid (res, self), FALSE); ++ task = G_TASK (res); ++ ++ g_warn_if_fail (g_task_get_source_tag (task) == goa_provider_remove_account_real); ++ ++ return g_task_propagate_boolean (task, error); ++} ++ ++/* ---------------------------------------------------------------------------------------------------- */ ++ + /** + * goa_provider_set_preseed_data: + * @self: The #GoaProvider +-- +2.5.5 + + +From 74ab19f5f6dafe7240b570923e8f5d4e4d47e474 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Fri, 20 May 2016 19:02:50 +0200 +Subject: [PATCH 14/22] daemon: Rename EnsureData as ObjectInvocationData + +... because we are also going to use it for Remove. + +https://bugzilla.gnome.org/show_bug.cgi?id=766733 +--- + src/daemon/goadaemon.c | 66 ++++++++++++++++++++++++++------------------------ + 1 file changed, 34 insertions(+), 32 deletions(-) + +diff --git a/src/daemon/goadaemon.c b/src/daemon/goadaemon.c +index c12030f2bbc2..01acd543da57 100644 +--- a/src/daemon/goadaemon.c ++++ b/src/daemon/goadaemon.c +@@ -1006,6 +1006,36 @@ on_manager_handle_add_account (GoaManager *manager, + + /* ---------------------------------------------------------------------------------------------------- */ + ++typedef struct ++{ ++ GoaDaemon *daemon; ++ GoaObject *object; ++ GDBusMethodInvocation *invocation; ++} ObjectInvocationData; ++ ++static ObjectInvocationData * ++object_invocation_data_new (GoaDaemon *self, ++ GoaObject *object, ++ GDBusMethodInvocation *invocation) ++{ ++ ObjectInvocationData *data; ++ data = g_slice_new0 (ObjectInvocationData); ++ data->daemon = g_object_ref (self); ++ data->object = g_object_ref (object); ++ data->invocation = invocation; ++ return data; ++} ++ ++static void ++object_invocation_data_unref (ObjectInvocationData *data) ++{ ++ g_object_unref (data->daemon); ++ g_object_unref (data->object); ++ g_slice_free (ObjectInvocationData, data); ++} ++ ++/* ---------------------------------------------------------------------------------------------------- */ ++ + static gboolean + on_account_handle_remove (GoaAccount *account, + GDBusMethodInvocation *invocation, +@@ -1105,34 +1135,6 @@ on_account_handle_remove (GoaAccount *account, + + /* ---------------------------------------------------------------------------------------------------- */ + +-typedef struct +-{ +- GoaDaemon *daemon; +- GoaObject *object; +- GDBusMethodInvocation *invocation; +-} EnsureData; +- +-static EnsureData * +-ensure_data_new (GoaDaemon *self, +- GoaObject *object, +- GDBusMethodInvocation *invocation) +-{ +- EnsureData *data; +- data = g_slice_new0 (EnsureData); +- data->daemon = g_object_ref (self); +- data->object = g_object_ref (object); +- data->invocation = invocation; +- return data; +-} +- +-static void +-ensure_data_unref (EnsureData *data) +-{ +- g_object_unref (data->daemon); +- g_object_unref (data->object); +- g_slice_free (EnsureData, data); +-} +- + static gboolean + is_authorization_error (GError *error) + { +@@ -1159,7 +1161,7 @@ ensure_credentials_cb (GoaProvider *provider, + GAsyncResult *res, + gpointer user_data) + { +- EnsureData *data = user_data; ++ ObjectInvocationData *data = user_data; + gint expires_in; + GError *error; + +@@ -1206,7 +1208,7 @@ ensure_credentials_cb (GoaProvider *provider, + if (data->invocation != NULL) + goa_account_complete_ensure_credentials (account, data->invocation, expires_in); + } +- ensure_data_unref (data); ++ object_invocation_data_unref (data); + } + + static gboolean +@@ -1235,7 +1237,7 @@ on_account_handle_ensure_credentials (GoaAccount *account, + object, + NULL, /* GCancellable */ + (GAsyncReadyCallback) ensure_credentials_cb, +- ensure_data_new (self, object, invocation)); ++ object_invocation_data_new (self, object, invocation)); + + out: + g_clear_object (&provider); +@@ -1277,7 +1279,7 @@ goa_daemon_check_credentials (GoaDaemon *self) + object, + NULL, /* GCancellable */ + (GAsyncReadyCallback) ensure_credentials_cb, +- ensure_data_new (self, object, NULL)); ++ object_invocation_data_new (self, object, NULL)); + + g_clear_object (&provider); + } +-- +2.5.5 + + +From a1d85d8b105dbf217a075e051f18f4ccbb9f3830 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Fri, 20 May 2016 19:51:28 +0200 +Subject: [PATCH 15/22] daemon: Call goa_provider_remove_account during account + removal + +https://bugzilla.gnome.org/show_bug.cgi?id=766733 +--- + src/daemon/goadaemon.c | 37 ++++++++++++++++++++++++++++++++++--- + 1 file changed, 34 insertions(+), 3 deletions(-) + +diff --git a/src/daemon/goadaemon.c b/src/daemon/goadaemon.c +index 01acd543da57..c0768cc28294 100644 +--- a/src/daemon/goadaemon.c ++++ b/src/daemon/goadaemon.c +@@ -1036,14 +1036,42 @@ object_invocation_data_unref (ObjectInvocationData *data) + + /* ---------------------------------------------------------------------------------------------------- */ + ++static void ++remove_account_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) ++{ ++ GError *error; ++ GoaAccount *account; ++ GoaProvider *provider = GOA_PROVIDER (source_object); ++ ObjectInvocationData *data = user_data; ++ ++ error= NULL; ++ if (!goa_provider_remove_account_finish (provider, res, &error)) ++ { ++ g_warning ("goa_provider_remove_account() failed: %s (%s, %d)", ++ error->message, ++ g_quark_to_string (error->domain), ++ error->code); ++ g_error_free (error); ++ } ++ ++ goa_daemon_reload_configuration (data->daemon); ++ ++ account = goa_object_peek_account (data->object); ++ goa_account_complete_remove (account, data->invocation); ++ ++ object_invocation_data_unref (data); ++} ++ + static gboolean + on_account_handle_remove (GoaAccount *account, + GDBusMethodInvocation *invocation, + gpointer user_data) + { + GoaDaemon *self = GOA_DAEMON (user_data); ++ GoaObject *object; + GoaProvider *provider; + GKeyFile *key_file; ++ ObjectInvocationData *data; + const gchar *provider_type; + gchar *path; + gchar *group; +@@ -1121,9 +1149,12 @@ on_account_handle_remove (GoaAccount *account, + goto out; + } + +- goa_daemon_reload_configuration (self); +- +- goa_account_complete_remove (account, invocation); ++ object = GOA_OBJECT (g_dbus_interface_get_object (G_DBUS_INTERFACE (account))); ++ goa_provider_remove_account (provider, ++ object, ++ NULL, ++ remove_account_cb, ++ object_invocation_data_new (self, object, invocation)); + + out: + g_clear_object (&provider); +-- +2.5.5 + + +From f8dabd85c19f611572eab515c8c098840828fcdd Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Fri, 20 May 2016 18:51:06 +0200 +Subject: [PATCH 16/22] kerberos: Implement GoaProvider:remove_account for + signing out + +... instead of listening to GoaClient::account-removed. + +GoaClient::account-removed is emitted every time the goa-daemon +process dies, which could be due to a crash or restart or something +else. We only want to sign out the identity when the user has +explicitly asked for it to be removed. We don't want to sign them out +merely because goa-daemon died. + +https://bugzilla.gnome.org/show_bug.cgi?id=766733 +--- + src/goabackend/goakerberosprovider.c | 72 ++++++++++++++++++++++++++++++++++++ + src/goaidentity/goaidentityservice.c | 43 --------------------- + 2 files changed, 72 insertions(+), 43 deletions(-) + +diff --git a/src/goabackend/goakerberosprovider.c b/src/goabackend/goakerberosprovider.c +index 9d6ddd65f995..f51f56a0a34a 100644 +--- a/src/goabackend/goakerberosprovider.c ++++ b/src/goabackend/goakerberosprovider.c +@@ -1463,6 +1463,76 @@ out: + return credentials_ensured; + } + ++/* ---------------------------------------------------------------------------------------------------- */ ++ ++static void ++remove_account_in_thread_func (GTask *task, ++ gpointer source_object, ++ gpointer task_data, ++ GCancellable *cancellable) ++{ ++ GError *error; ++ GoaAccount *account = NULL; ++ GoaObject *object = GOA_OBJECT (task_data); ++ const gchar *identifier; ++ ++ ensure_identity_manager (); ++ ++ account = goa_object_get_account (object); ++ identifier = goa_account_get_identity (account); ++ ++ g_debug ("Kerberos account %s removed and should now be signed out", identifier); ++ ++ error = NULL; ++ if (!goa_identity_service_manager_call_sign_out_sync (identity_manager, identifier, cancellable, &error)) ++ { ++ g_task_return_error (task, error); ++ goto out; ++ } ++ ++ g_task_return_boolean (task, TRUE); ++ ++ out: ++ g_clear_object (&account); ++} ++ ++static void ++remove_account (GoaProvider *provider, ++ GoaObject *object, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data) ++{ ++ GoaKerberosProvider *self = GOA_KERBEROS_PROVIDER (provider); ++ GTask *task; ++ ++ task = g_task_new (self, cancellable, callback, user_data); ++ g_task_set_source_tag (task, remove_account); ++ ++ g_task_set_task_data (task, g_object_ref (object), g_object_unref); ++ g_task_run_in_thread (task, remove_account_in_thread_func); ++ ++ g_object_unref (task); ++} ++ ++static gboolean ++remove_account_finish (GoaProvider *provider, ++ GAsyncResult *res, ++ GError **error) ++{ ++ GoaKerberosProvider *self = GOA_KERBEROS_PROVIDER (provider); ++ GTask *task; ++ ++ g_return_val_if_fail (g_task_is_valid (res, self), FALSE); ++ task = G_TASK (res); ++ ++ g_warn_if_fail (g_task_get_source_tag (task) == remove_account); ++ ++ return g_task_propagate_boolean (task, error); ++} ++ ++/* ---------------------------------------------------------------------------------------------------- */ ++ + static GoaIdentityServiceIdentity * + get_identity_from_object_manager (GoaKerberosProvider *self, + const char *identifier) +@@ -1707,4 +1777,6 @@ goa_kerberos_provider_class_init (GoaKerberosProviderClass *kerberos_class) + provider_class->refresh_account = refresh_account; + provider_class->show_account = show_account; + provider_class->ensure_credentials_sync = ensure_credentials_sync; ++ provider_class->remove_account = remove_account; ++ provider_class->remove_account_finish = remove_account_finish; + } +diff --git a/src/goaidentity/goaidentityservice.c b/src/goaidentity/goaidentityservice.c +index 2eda31d56e74..fdc161fe97ab 100644 +--- a/src/goaidentity/goaidentityservice.c ++++ b/src/goaidentity/goaidentityservice.c +@@ -1526,44 +1526,6 @@ on_account_interface_removed (GDBusObjectManager *manager, + } + + static void +-on_account_removed (GoaClient *client, +- GoaObject *object, +- GoaIdentityService *self) +-{ +- GSimpleAsyncResult *result; +- GoaAccount *account; +- const char *provider_type; +- const char *account_identity; +- +- account = goa_object_peek_account (object); +- +- if (account == NULL) +- return; +- +- provider_type = goa_account_get_provider_type (account); +- +- if (g_strcmp0 (provider_type, "kerberos") != 0) +- return; +- +- account_identity = goa_account_get_identity (account); +- +- g_debug ("Kerberos account %s removed and should now be signed out", account_identity); +- +- result = g_simple_async_result_new (G_OBJECT (self), +- (GAsyncReadyCallback) +- on_sign_out_for_account_change_done, +- NULL, +- on_account_removed); +- +- goa_identity_manager_get_identity (self->priv->identity_manager, +- account_identity, +- NULL, +- (GAsyncReadyCallback) +- on_got_identity_for_sign_out, +- result); +-} +- +-static void + on_identities_listed (GoaIdentityManager *manager, + GAsyncResult *result, + GoaIdentityService *self) +@@ -1596,11 +1558,6 @@ on_identities_listed (GoaIdentityManager *manager, + G_CALLBACK (on_identity_expired), + self); + +- g_signal_connect (G_OBJECT (self->priv->client), +- "account-removed", +- G_CALLBACK (on_account_removed), +- self); +- + identities = goa_identity_manager_list_identities_finish (manager, result, &error); + + if (identities == NULL) +-- +2.5.5 + + +From 09e9884bb982e340357b89a51e0f88245e38ebff Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Thu, 26 May 2016 19:07:01 +0200 +Subject: [PATCH 17/22] daemon: Add a synchronous version of + goa_provider_get_all + +This will be useful to poke at all available providers when goa-daemon +starts. Since we are doing this in the early stages of start-up, it +would be nice to be able to get the list of providers synchronously. + +This function is not suitable for wider use because we can't push a +new thread-default GMainContext due to limitations (or bugs) inside +telepathy-glib. + +https://bugzilla.gnome.org/show_bug.cgi?id=766733 +--- + src/daemon/goadaemon.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 46 insertions(+) + +diff --git a/src/daemon/goadaemon.c b/src/daemon/goadaemon.c +index c0768cc28294..2e3b12c3efe9 100644 +--- a/src/daemon/goadaemon.c ++++ b/src/daemon/goadaemon.c +@@ -80,6 +80,52 @@ static void goa_daemon_reload_configuration (GoaDaemon *self); + + G_DEFINE_TYPE (GoaDaemon, goa_daemon, G_TYPE_OBJECT); + ++/* ---------------------------------------------------------------------------------------------------- */ ++ ++typedef struct ++{ ++ GError **error; ++ GList **out_providers; ++ GMainLoop *loop; ++ gboolean op_res; ++} GetAllSyncData; ++ ++static void ++get_all_providers_sync_cb (GObject *source_object, ++ GAsyncResult *res, ++ gpointer user_data) ++{ ++ GetAllSyncData *data = (GetAllSyncData *) user_data; ++ ++ data->op_res = goa_provider_get_all_finish (data->out_providers, res, data->error); ++ g_main_loop_quit (data->loop); ++} ++ ++static gboolean ++get_all_providers_sync (GCancellable *cancellable, ++ GList **out_providers, ++ GError **error) ++{ ++ GetAllSyncData data; ++ ++ data.error = error; ++ data.out_providers = out_providers; ++ ++ /* HACK: Since telepathy-glib doesn't use the thread-default ++ * GMainContext for invoking the asynchronous callbacks, we can't ++ * push a new GMainContext here. ++ */ ++ data.loop = g_main_loop_new (NULL, FALSE); ++ ++ goa_provider_get_all (get_all_providers_sync_cb, &data); ++ g_main_loop_run (data.loop); ++ g_main_loop_unref (data.loop); ++ ++ return data.op_res; ++} ++ ++/* ---------------------------------------------------------------------------------------------------- */ ++ + static void + goa_daemon_finalize (GObject *object) + { +-- +2.5.5 + + +From 07237f1ab7651b808a11bdcbefeafe6909718165 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Thu, 26 May 2016 19:08:41 +0200 +Subject: [PATCH 18/22] provider: Add a new vfunc for backend-specific + initialization + +https://bugzilla.gnome.org/show_bug.cgi?id=766733 +--- + src/goabackend/goaprovider-priv.h | 4 ++++ + src/goabackend/goaprovider.c | 18 ++++++++++++++++++ + 2 files changed, 22 insertions(+) + +diff --git a/src/goabackend/goaprovider-priv.h b/src/goabackend/goaprovider-priv.h +index 762989158807..c7b0f59860bd 100644 +--- a/src/goabackend/goaprovider-priv.h ++++ b/src/goabackend/goaprovider-priv.h +@@ -52,6 +52,7 @@ struct _GoaProvider + * @ensure_credentials_sync: Virtual function for goa_provider_ensure_credentials_sync(). + * @show_account: Virtual function for goa_provider_show_account(). + * @get_credentials_generation: Virtual function for goa_provider_get_credentials_generation(). ++ * @initialize: Virtual function for goa_provider_initialize(). + * + * Class structure for #GoaProvider. + */ +@@ -98,6 +99,7 @@ struct _GoaProviderClass + guint (*get_credentials_generation) (GoaProvider *self); + GIcon *(*get_provider_icon) (GoaProvider *self, + GoaObject *object); ++ void (*initialize) (GoaProvider *self); + void (*remove_account) (GoaProvider *self, + GoaObject *object, + GCancellable *cancellable, +@@ -126,6 +128,8 @@ void goa_provider_ensure_builtins_loaded (void); + + void goa_provider_ensure_extension_points_registered (void); + ++void goa_provider_initialize (GoaProvider *self); ++ + void goa_provider_remove_account (GoaProvider *self, + GoaObject *object, + GCancellable *cancellable, +diff --git a/src/goabackend/goaprovider.c b/src/goabackend/goaprovider.c +index 174fe9ac67be..f07fa95187fc 100644 +--- a/src/goabackend/goaprovider.c ++++ b/src/goabackend/goaprovider.c +@@ -81,6 +81,8 @@ static guint goa_provider_get_credentials_generation_real (GoaProvider *self); + static GIcon *goa_provider_get_provider_icon_real (GoaProvider *self, + GoaObject *object); + ++static void goa_provider_initialize_real (GoaProvider *self); ++ + static void goa_provider_remove_account_real (GoaProvider *self, + GoaObject *object, + GCancellable *cancellable, +@@ -162,6 +164,7 @@ goa_provider_class_init (GoaProviderClass *klass) + klass->ensure_credentials_sync = goa_provider_ensure_credentials_sync_real; + klass->get_credentials_generation = goa_provider_get_credentials_generation_real; + klass->get_provider_icon = goa_provider_get_provider_icon_real; ++ klass->initialize = goa_provider_initialize_real; + klass->remove_account = goa_provider_remove_account_real; + klass->remove_account_finish = goa_provider_remove_account_finish_real; + +@@ -330,6 +333,21 @@ goa_provider_get_provider_features (GoaProvider *self) + + /* ---------------------------------------------------------------------------------------------------- */ + ++void ++goa_provider_initialize (GoaProvider *self) ++{ ++ g_return_if_fail (GOA_IS_PROVIDER (self)); ++ ++ GOA_PROVIDER_GET_CLASS (self)->initialize (self); ++} ++ ++static void ++goa_provider_initialize_real (GoaProvider *self) ++{ ++} ++ ++/* ---------------------------------------------------------------------------------------------------- */ ++ + /** + * goa_provider_add_account: + * @self: A #GoaProvider. +-- +2.5.5 + + +From 981298802f9b7596d241c98a8f9a546f30816372 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Thu, 26 May 2016 19:09:24 +0200 +Subject: [PATCH 19/22] daemon: Call goa_provider_initialize during start-up + +https://bugzilla.gnome.org/show_bug.cgi?id=766733 +--- + src/daemon/goadaemon.c | 19 ++++++++++++++++++- + 1 file changed, 18 insertions(+), 1 deletion(-) + +diff --git a/src/daemon/goadaemon.c b/src/daemon/goadaemon.c +index 2e3b12c3efe9..f3995cf8c369 100644 +--- a/src/daemon/goadaemon.c ++++ b/src/daemon/goadaemon.c +@@ -251,6 +251,9 @@ static void + goa_daemon_init (GoaDaemon *self) + { + static volatile GQuark goa_error_domain = 0; ++ GError *error; ++ GList *l; ++ GList *providers = NULL; + GoaObjectSkeleton *object; + gchar *path; + +@@ -260,7 +263,21 @@ goa_daemon_init (GoaDaemon *self) + goa_error_domain = GOA_ERROR; + goa_error_domain; /* shut up -Wunused-but-set-variable */ + +- goa_provider_ensure_builtins_loaded (); ++ error = NULL; ++ if (!get_all_providers_sync (NULL, &providers, &error)) ++ { ++ g_warning ("Unable to get the list of providers: %s (%s, %d)", ++ error->message, ++ g_quark_to_string (error->domain), ++ error->code); ++ g_error_free (error); ++ } ++ ++ for (l = providers; l != NULL; l = l->next) ++ { ++ GoaProvider *provider = GOA_PROVIDER (l->data); ++ goa_provider_initialize (provider); ++ } + + /* TODO: maybe nicer to pass in a GDBusConnection* construct property */ + self->connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); +-- +2.5.5 + + +From e9748cc601a4e7cd3ebe6dd31151d91e88569fad Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Thu, 26 May 2016 19:31:28 +0200 +Subject: [PATCH 20/22] telepathy: Implement GoaProvider:initialize to start + the linker + +... instead of starting it from goa-daemon. + +https://bugzilla.gnome.org/show_bug.cgi?id=766733 +--- + src/daemon/Makefile.am | 3 - + src/daemon/goatpaccountlinker.c | 590 ---------------------------------- + src/daemon/goatpaccountlinker.h | 54 ---- + src/daemon/main.c | 7 - + src/goabackend/Makefile.am | 1 + + src/goabackend/goatelepathyprovider.c | 39 +++ + src/goabackend/goatpaccountlinker.c | 590 ++++++++++++++++++++++++++++++++++ + src/goabackend/goatpaccountlinker.h | 54 ++++ + 8 files changed, 684 insertions(+), 654 deletions(-) + delete mode 100644 src/daemon/goatpaccountlinker.c + delete mode 100644 src/daemon/goatpaccountlinker.h + create mode 100644 src/goabackend/goatpaccountlinker.c + create mode 100644 src/goabackend/goatpaccountlinker.h + +diff --git a/src/daemon/Makefile.am b/src/daemon/Makefile.am +index 8f5352fad39e..b318b6a4a328 100644 +--- a/src/daemon/Makefile.am ++++ b/src/daemon/Makefile.am +@@ -29,14 +29,12 @@ goa_daemon_SOURCES = \ + main.c \ + goadaemontypes.h \ + goadaemon.h goadaemon.c \ +- goatpaccountlinker.h goatpaccountlinker.c \ + $(NULL) + + goa_daemon_CFLAGS = \ + $(GLIB_CFLAGS) \ + $(GTK_CFLAGS) \ + $(REST_CFLAGS) \ +- $(TP_CFLAGS) \ + $(NULL) + + goa_daemon_LDADD = \ +@@ -45,7 +43,6 @@ goa_daemon_LDADD = \ + $(top_builddir)/src/goabackend/libgoa-backend-1.0.la \ + $(GTK_LIBS) \ + $(REST_LIBS) \ +- $(TP_LIBS) \ + $(NULL) + + clean-local : +diff --git a/src/daemon/goatpaccountlinker.c b/src/daemon/goatpaccountlinker.c +deleted file mode 100644 +index dcdf3f761ca7..000000000000 +--- a/src/daemon/goatpaccountlinker.c ++++ /dev/null +@@ -1,590 +0,0 @@ +-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +-/* +- * Copyright (C) 2010-2013 Collabora Ltd. +- * Copyright (C) 2013 Intel Corporation +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General +- * Public License along with this library; if not, see . +- */ +- +-/* This class makes sure we have a GOA account for each Telepathy account +- * configured in the system. +- * Note that this handles only plain Telepathy accounts; the ones with +- * multiple capabilities (e.g. Facebook) are handled differently. */ +- +-#include "config.h" +- +-#include +-#include +- +-#include "goatpaccountlinker.h" +-#include "goa/goa.h" +-#include "goabackend/goautils.h" +- +-#define GOA_TP_ACCOUNT_LINKER_GET_PRIVATE(obj) \ +- (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GOA_TYPE_TP_ACCOUNT_LINKER, \ +- GoaTpAccountLinkerPrivate)) +- +-G_DEFINE_TYPE (GoaTpAccountLinker, goa_tp_account_linker, G_TYPE_OBJECT) +- +-struct _GoaTpAccountLinkerPrivate +-{ +- TpAccountManager *account_manager; +- GoaClient *goa_client; +- +- GHashTable *tp_accounts; /* owned gchar *id -> reffed TpAccount * */ +- GHashTable *goa_accounts; /* owned gchar *id -> reffed GoaObject * */ +-}; +- +-/* The path of the Telepathy account is used as common identifier between +- * GOA and Telepathy */ +-static const gchar * +-get_id_from_tp_account (TpAccount *tp_account) +-{ +- return tp_proxy_get_object_path (tp_account); +-} +- +-static const gchar * +-get_id_from_goa_account (GoaAccount *goa_account) +-{ +- return goa_account_get_identity (goa_account); +-} +- +-static gboolean +-is_telepathy_account (GoaAccount *goa_account) +-{ +- const gchar *type = goa_account_get_provider_type (goa_account); +- return g_str_has_prefix (type, "telepathy/"); +-} +- +-static void +-goa_account_chat_disabled_changed_cb (GoaAccount *goa_account, +- GParamSpec *spec, +- GoaTpAccountLinker *self) +-{ +- GoaTpAccountLinkerPrivate *priv = self->priv; +- const gchar *id; +- TpAccount *tp_account; +- gboolean tp_enabled; +- gboolean goa_enabled; +- +- id = get_id_from_goa_account (goa_account); +- tp_account = g_hash_table_lookup (priv->tp_accounts, id); +- if (tp_account == NULL) +- return; +- +- goa_enabled = !goa_account_get_chat_disabled (goa_account); +- tp_enabled = tp_account_is_enabled (tp_account); +- if (tp_enabled != goa_enabled) +- { +- g_info ("The GOA account %s (Telepathy object path: %s) has been %s, " +- "propagating to Telepathy", +- goa_account_get_id (goa_account), id, +- goa_enabled ? "enabled" : "disabled"); +- tp_account_set_enabled_async (tp_account, goa_enabled, NULL, NULL); +- } +-} +- +-static void +-tp_account_chat_enabled_changed_cb (TpAccount *tp_account, +- GParamSpec *spec, +- GoaTpAccountLinker *self) +-{ +- GoaTpAccountLinkerPrivate *priv = self->priv; +- const gchar *id; +- GoaObject *goa_object; +- GoaAccount *goa_account; +- gboolean tp_enabled; +- gboolean goa_enabled; +- +- id = get_id_from_tp_account (tp_account); +- goa_object = g_hash_table_lookup (priv->goa_accounts, id); +- if (goa_object == NULL) +- return; +- +- goa_account = goa_object_peek_account (goa_object); +- goa_enabled = !goa_account_get_chat_disabled (goa_account); +- tp_enabled = tp_account_is_enabled (tp_account); +- if (tp_enabled != goa_enabled) +- { +- g_info ("The Telepathy account %s has been %s, propagating to GOA", +- id, tp_enabled ? "enabled" : "disabled"); +- /* When we set this property, the autogenerated code emits a notify +- * signal immediately even if the property hasn't changed, so +- * goa_account_chat_disabled_changed_cb() thinks that the property +- * changed back to the old value and a cycle starts. +- * The right notify signal will be emitted later when the property is +- * actually changed. */ +- g_signal_handlers_block_by_func (goa_account, +- goa_account_chat_disabled_changed_cb, self); +- goa_account_set_chat_disabled (goa_account, !tp_enabled); +- g_signal_handlers_unblock_by_func (goa_account, +- goa_account_chat_disabled_changed_cb, self); +- } +-} +- +-static void +-goa_account_created_cb (GoaManager *manager, +- GAsyncResult *res, +- gpointer user_data) +-{ +- TpAccount *tp_account = user_data; +- gchar *goa_account_object_path = NULL; +- GError *error = NULL; +- +- if (!goa_manager_call_add_account_finish (manager, +- &goa_account_object_path, res, &error)) +- { +- g_critical ("Failed to create a GOA account for %s: %s (%s, %d)", +- get_id_from_tp_account (tp_account), +- error->message, +- g_quark_to_string (error->domain), +- error->code); +- g_error_free (error); +- goto out; +- } +- +- g_info ("Created new %s GOA account for Telepathy account %s", +- goa_account_object_path, get_id_from_tp_account (tp_account)); +- +- out: +- g_object_unref (tp_account); +-} +- +-static void +-create_goa_account (GoaTpAccountLinker *self, +- TpAccount *tp_account) +-{ +- GoaTpAccountLinkerPrivate *priv = self->priv; +- GVariantBuilder credentials; +- GVariantBuilder details; +- gchar *provider; +- +- g_info ("Creating new GOA account for Telepathy account %s", +- get_id_from_tp_account (tp_account)); +- +- g_variant_builder_init (&credentials, G_VARIANT_TYPE_VARDICT); +- +- g_variant_builder_init (&details, G_VARIANT_TYPE ("a{ss}")); +- g_variant_builder_add (&details, "{ss}", "ChatEnabled", +- tp_account_is_enabled (tp_account) ? "true" : "false"); +- +- provider = g_strdup_printf ("telepathy/%s", +- tp_account_get_protocol_name (tp_account)); +- +- goa_manager_call_add_account (goa_client_get_manager (priv->goa_client), +- provider, +- get_id_from_tp_account (tp_account), +- tp_account_get_display_name (tp_account), +- g_variant_builder_end (&credentials), +- g_variant_builder_end (&details), +- NULL, /* GCancellable* */ +- (GAsyncReadyCallback) goa_account_created_cb, +- g_object_ref (tp_account)); +- +- g_free (provider); +-} +- +-static gboolean +-is_account_filtered (TpAccount *tp_account) +-{ +- const gchar *env; +- const gchar *id; +- +- env = g_getenv ("GOA_TELEPATHY_DEBUG_ACCOUNT_FILTER"); +- if (env == NULL || env[0] == '\0') +- return FALSE; +- +- id = get_id_from_tp_account (tp_account); +- if (g_strstr_len (id, -1, env) != NULL) +- return FALSE; /* "env" is contained in "id" */ +- else +- return TRUE; +-} +- +-static void +-tp_account_added (GoaTpAccountLinker *self, +- TpAccount *tp_account) +-{ +- GoaTpAccountLinkerPrivate *priv = self->priv; +- const gchar *id = get_id_from_tp_account (tp_account); +- GoaObject *goa_object = NULL; +- +- if (g_strcmp0 (tp_account_get_storage_provider (tp_account), +- "org.gnome.OnlineAccounts") == 0) +- { +- g_debug ("Skipping Telepathy account %s as it's handled directly by GOA", id); +- return; +- } +- +- if (is_account_filtered (tp_account)) +- { +- g_debug ("The account %s is ignored for debugging reasons", id); +- return; +- } +- +- g_debug ("Telepathy account found: %s", id); +- +- g_hash_table_replace (priv->tp_accounts, g_strdup (id), +- g_object_ref (tp_account)); +- +- g_signal_connect_object (tp_account, "notify::enabled", +- G_CALLBACK (tp_account_chat_enabled_changed_cb), +- self, 0); +- +- goa_object = g_hash_table_lookup (priv->goa_accounts, id); +- if (goa_object == NULL) +- { +- g_debug ("Found a Telepathy account with no corresponding " +- "GOA account: %s", id); +- create_goa_account (self, tp_account); +- } +- else +- { +- g_debug ("Found a Telepathy account with a matching " +- "GOA account: %s", id); +- /* Make sure the initial state is synced. */ +- tp_account_chat_enabled_changed_cb (tp_account, NULL, self); +- } +-} +- +-static void +-goa_account_removed_by_us_cb (GObject *object, +- GAsyncResult *res, +- gpointer user_data) +-{ +- /* This callback is only used for debugging */ +- GoaAccount *goa_account = GOA_ACCOUNT (object); +- GError *error = NULL; +- +- if (!goa_account_call_remove_finish (goa_account, res, &error)) +- { +- g_critical ("Error removing GOA account %s (Telepathy object path: %s): " +- "%s (%s, %d)", +- goa_account_get_id (goa_account), +- get_id_from_goa_account (goa_account), +- error->message, +- g_quark_to_string (error->domain), +- error->code); +- g_error_free (error); +- } +-} +- +-static void +-tp_account_removed_cb (TpAccountManager *manager, +- TpAccount *tp_account, +- gpointer user_data) +-{ +- GoaTpAccountLinker *self = user_data; +- GoaTpAccountLinkerPrivate *priv = self->priv; +- const gchar *id = get_id_from_tp_account (tp_account); +- GoaObject *goa_object = NULL; +- +- if (!g_hash_table_remove (priv->tp_accounts, id)) +- { +- /* 1 - The user removes the GOA account +- * 2 - We delete the corresponding Telepathy account and remove it +- * from priv->tp_accounts +- * 3 - "account-removed" is emitted by the account manager +- * 4 - tp_account_removed_cb is called for an unknown account +- */ +- g_debug ("Ignoring removal of Telepathy account we asked to " +- "remove (%s)", id); +- return; +- } +- +- g_info ("Telepathy account %s removed, removing corresponding " +- "GOA account", id); +- +- goa_object = g_hash_table_lookup (priv->goa_accounts, id); +- if (goa_object == NULL) +- { +- g_critical ("There is no GOA account for removed Telepathy " +- "account %s", id); +- return; +- } +- goa_account_call_remove (goa_object_peek_account (goa_object), +- NULL, /* cancellable */ +- goa_account_removed_by_us_cb, NULL); +- g_hash_table_remove (priv->goa_accounts, id); +-} +- +-static void +-tp_account_validity_changed_cb (TpAccountManager *manager, +- TpAccount *tp_account, +- gboolean valid, +- gpointer user_data) +-{ +- GoaTpAccountLinker *self = user_data; +- +- if (valid) +- tp_account_added (self, tp_account); +-} +- +-static void +-goa_account_added_cb (GoaClient *client, +- GoaObject *goa_object, +- gpointer user_data) +-{ +- GoaTpAccountLinker *self = user_data; +- GoaTpAccountLinkerPrivate *priv = self->priv; +- GoaAccount *goa_account = goa_object_peek_account (goa_object); +- const gchar *id = NULL; +- TpAccount *tp_account; +- +- if (!is_telepathy_account (goa_account)) +- return; +- +- id = get_id_from_goa_account (goa_account); +- g_debug ("GOA account %s for Telepathy account %s added", +- goa_account_get_id (goa_account), id); +- +- g_signal_connect_object (goa_account, "notify::chat-disabled", +- G_CALLBACK (goa_account_chat_disabled_changed_cb), self, 0); +- +- g_hash_table_insert (priv->goa_accounts, g_strdup (id), +- g_object_ref (goa_object)); +- +- tp_account = g_hash_table_lookup (priv->tp_accounts, id); +- if (tp_account != NULL) +- { +- /* The chat enabled status may have changed during the creation of the +- * GOA account, so we need to make sure it's synced. */ +- tp_account_chat_enabled_changed_cb (tp_account, NULL, self); +- } +-} +- +-static void +-tp_account_removed_by_us_cb (GObject *object, +- GAsyncResult *res, +- gpointer user_data) +-{ +- /* This callback is only used for debugging */ +- TpAccount *tp_account = TP_ACCOUNT (object); +- GError *error = NULL; +- +- if (!tp_account_remove_finish (tp_account, res, &error)) +- { +- g_critical ("Error removing Telepathy account %s: %s (%s, %d)", +- get_id_from_tp_account (tp_account), +- error->message, +- g_quark_to_string (error->domain), +- error->code); +- g_error_free (error); +- } +-} +- +-static void +-goa_account_removed_cb (GoaClient *client, +- GoaObject *goa_object, +- gpointer user_data) +-{ +- GoaTpAccountLinker *self = user_data; +- GoaTpAccountLinkerPrivate *priv = self->priv; +- GoaAccount *goa_account = goa_object_peek_account (goa_object); +- const gchar *id = NULL; +- TpAccount *tp_account = NULL; +- +- if (!is_telepathy_account (goa_account)) +- return; +- +- id = get_id_from_goa_account (goa_account); +- if (!g_hash_table_remove (priv->goa_accounts, id)) +- { +- /* 1 - The user removes the Telepathy account (but not the GOA one) +- * 2 - We delete the corresponding GOA account and remove it +- * from priv->goa_accounts +- * 3 - "account-removed" is emitted by the GOA client +- * 4 - goa_account_removed_cb is called for an unknown account +- */ +- g_debug ("Ignoring removal of GOA account we asked to remove " +- "(%s, Telepathy object path: %s)", +- goa_account_get_id (goa_account), +- id); +- return; +- } +- +- g_info ("GOA account %s for Telepathy account %s removed, " +- "removing Telepathy account", +- goa_account_get_id (goa_account), id); +- +- tp_account = g_hash_table_lookup (priv->tp_accounts, id); +- if (tp_account == NULL) +- { +- g_critical ("There is no Telepathy account for removed GOA " +- "account %s (Telepathy object path: %s)", +- goa_account_get_id (goa_account), id); +- return; +- } +- tp_account_remove_async (tp_account, tp_account_removed_by_us_cb, NULL); +- g_hash_table_remove (priv->tp_accounts, id); +-} +- +-static void +-start_if_ready (GoaTpAccountLinker *self) +-{ +- GoaTpAccountLinkerPrivate *priv = self->priv; +- GList *goa_accounts = NULL; +- GList *tp_accounts = NULL; +- GList *l = NULL; +- GHashTableIter iter; +- gpointer key, value; +- +- if (priv->goa_client == NULL || +- priv->account_manager == NULL || +- !tp_proxy_is_prepared (priv->account_manager, +- TP_ACCOUNT_MANAGER_FEATURE_CORE)) +- { +- /* Not everything is ready yet */ +- return; +- } +- +- g_debug ("Both GOA and Tp are ready, starting tracking of accounts"); +- +- /* GOA */ +- goa_accounts = goa_client_get_accounts (priv->goa_client); +- for (l = goa_accounts; l != NULL; l = l->next) +- goa_account_added_cb (priv->goa_client, l->data, self); +- g_list_free_full (goa_accounts, g_object_unref); +- +- g_signal_connect_object (priv->goa_client, "account-added", +- G_CALLBACK (goa_account_added_cb), self, 0); +- g_signal_connect_object (priv->goa_client, "account-removed", +- G_CALLBACK (goa_account_removed_cb), self, 0); +- +- /* Telepathy */ +- tp_accounts = tp_account_manager_dup_valid_accounts (priv->account_manager); +- for (l = tp_accounts; l != NULL; l = l->next) +- tp_account_added (self, l->data); +- g_list_free_full (tp_accounts, g_object_unref); +- +- g_signal_connect_object (priv->account_manager, "account-validity-changed", +- G_CALLBACK (tp_account_validity_changed_cb), self, 0); +- g_signal_connect_object (priv->account_manager, "account-removed", +- G_CALLBACK (tp_account_removed_cb), self, 0); +- +- /* Now we check if any Telepathy account was deleted while goa-daemon +- * was not running. */ +- g_hash_table_iter_init (&iter, priv->goa_accounts); +- while (g_hash_table_iter_next (&iter, &key, &value)) +- { +- const gchar *id = key; +- GoaObject *goa_object = value; +- +- if (!g_hash_table_lookup (priv->tp_accounts, id)) +- { +- g_warning ("The Telepathy account %s was removed while the daemon " +- "was not running, removing the corresponding GOA account", id); +- goa_account_call_remove (goa_object_peek_account (goa_object), +- NULL, /* cancellable */ +- goa_account_removed_by_us_cb, +- NULL); /* user data */ +- } +- } +-} +- +-static void +-account_manager_prepared_cb (GObject *object, +- GAsyncResult *res, +- gpointer user_data) +-{ +- GoaTpAccountLinker *self = user_data; +- GError *error = NULL; +- +- if (!tp_proxy_prepare_finish (object, res, &error)) +- { +- g_critical ("Error preparing AM: %s", error->message); +- g_clear_error (&error); +- return; +- } +- +- g_debug("Telepathy account manager prepared"); +- start_if_ready (self); +-} +- +-static void +-goa_client_new_cb (GObject *object, +- GAsyncResult *result, +- gpointer user_data) +-{ +- GoaTpAccountLinker *self = user_data; +- GoaTpAccountLinkerPrivate *priv = self->priv; +- GError *error = NULL; +- +- priv->goa_client = goa_client_new_finish (result, &error); +- if (priv->goa_client == NULL) +- { +- g_critical ("Error connecting to GOA: %s", error->message); +- g_clear_error (&error); +- return; +- } +- +- g_debug("GOA client ready"); +- start_if_ready (self); +-} +- +-static void +-goa_tp_account_linker_dispose (GObject *object) +-{ +- GoaTpAccountLinker *self = GOA_TP_ACCOUNT_LINKER (object); +- GoaTpAccountLinkerPrivate *priv = self->priv; +- +- g_clear_object (&priv->account_manager); +- g_clear_object (&priv->goa_client); +- +- g_clear_pointer (&priv->goa_accounts, g_hash_table_unref); +- g_clear_pointer (&priv->tp_accounts, g_hash_table_unref); +- +- G_OBJECT_CLASS (goa_tp_account_linker_parent_class)->dispose (object); +-} +- +-static void +-goa_tp_account_linker_init (GoaTpAccountLinker *self) +-{ +- GoaTpAccountLinkerPrivate *priv; +- +- g_debug ("Starting GOA <-> Telepathy account linker"); +- +- self->priv = GOA_TP_ACCOUNT_LINKER_GET_PRIVATE (self); +- priv = self->priv; +- +- priv->goa_accounts = g_hash_table_new_full (g_str_hash, g_str_equal, +- g_free, g_object_unref); +- priv->tp_accounts = g_hash_table_new_full (g_str_hash, g_str_equal, +- g_free, g_object_unref); +- +- priv->account_manager = tp_account_manager_dup (); +- tp_proxy_prepare_async (priv->account_manager, NULL, +- account_manager_prepared_cb, self); +- +- goa_client_new (NULL, goa_client_new_cb, self); +-} +- +-static void +-goa_tp_account_linker_class_init (GoaTpAccountLinkerClass *klass) +-{ +- GObjectClass *gobject_class = G_OBJECT_CLASS (klass); +- +- goa_utils_initialize_client_factory (); +- +- g_type_class_add_private (gobject_class, +- sizeof (GoaTpAccountLinkerPrivate)); +- +- gobject_class->dispose = goa_tp_account_linker_dispose; +-} +- +-GoaTpAccountLinker * +-goa_tp_account_linker_new (void) +-{ +- return g_object_new (GOA_TYPE_TP_ACCOUNT_LINKER, NULL); +-} +diff --git a/src/daemon/goatpaccountlinker.h b/src/daemon/goatpaccountlinker.h +deleted file mode 100644 +index 3f5b12955df0..000000000000 +--- a/src/daemon/goatpaccountlinker.h ++++ /dev/null +@@ -1,54 +0,0 @@ +-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +-/* +- * Copyright (C) 2010-2013 Collabora Ltd. +- * Copyright (C) 2013 Intel Corporation +- * +- * This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU Lesser General Public +- * License as published by the Free Software Foundation; either +- * version 2 of the License, or (at your option) any later version. +- * +- * This library 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 +- * Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General +- * Public License along with this library; if not, see . +- */ +- +-#ifndef __GOA_TP_ACCOUNT_LINKER_H__ +-#define __GOA_TP_ACCOUNT_LINKER_H__ +- +-#include +- +-G_BEGIN_DECLS +- +-#define GOA_TYPE_TP_ACCOUNT_LINKER (goa_tp_account_linker_get_type ()) +-#define GOA_TP_ACCOUNT_LINKER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOA_TYPE_TP_ACCOUNT_LINKER, GoaTpAccountLinker)) +-#define GOA_TP_ACCOUNT_LINKER_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST ((obj), GOA_TYPE_TP_ACCOUNT_LINKER, GoaTpAccountLinkerClass)) +-#define GOA_IS_TP_ACCOUNT_LINKER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GOA_TYPE_TP_ACCOUNT_LINKER)) +-#define GOA_IS_TP_ACCOUNT_LINKER_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((obj), GOA_TYPE_TP_ACCOUNT_LINKER)) +-#define GOA_TP_ACCOUNT_LINKER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GOA_TYPE_TP_ACCOUNT_LINKER, GoaTpAccountLinkerClass)) +- +-typedef struct _GoaTpAccountLinker GoaTpAccountLinker; +-typedef struct _GoaTpAccountLinkerClass GoaTpAccountLinkerClass; +-typedef struct _GoaTpAccountLinkerPrivate GoaTpAccountLinkerPrivate; +- +-struct _GoaTpAccountLinker +-{ +- GObject parent_instance; +- GoaTpAccountLinkerPrivate *priv; +-}; +- +-struct _GoaTpAccountLinkerClass +-{ +- GObjectClass parent_class; +-}; +- +-GType goa_tp_account_linker_get_type (void) G_GNUC_CONST; +-GoaTpAccountLinker *goa_tp_account_linker_new (void); +- +-G_END_DECLS +- +-#endif +diff --git a/src/daemon/main.c b/src/daemon/main.c +index a04cc3992a83..0d1b24f51062 100644 +--- a/src/daemon/main.c ++++ b/src/daemon/main.c +@@ -25,8 +25,6 @@ + #include + + #include "goadaemon.h" +-#include "goatpaccountlinker.h" +- + + /* ---------------------------------------------------------------------------------------------------- */ + +@@ -40,7 +38,6 @@ static GOptionEntry opt_entries[] = + {NULL } + }; + static GoaDaemon *the_daemon = NULL; +-static GoaTpAccountLinker *tp_linker = NULL; + + static void + on_bus_acquired (GDBusConnection *connection, +@@ -67,8 +64,6 @@ on_name_acquired (GDBusConnection *connection, + gpointer user_data) + { + g_debug ("Acquired the name %s on the session message bus", name); +- +- tp_linker = goa_tp_account_linker_new (); + } + + static gboolean +@@ -131,8 +126,6 @@ main (int argc, + out: + if (the_daemon != NULL) + g_object_unref (the_daemon); +- if (tp_linker != NULL) +- g_object_unref (tp_linker); + if (name_owner_id != 0) + g_bus_unown_name (name_owner_id); + g_clear_pointer (&loop, (GDestroyNotify) g_main_loop_unref); +diff --git a/src/goabackend/Makefile.am b/src/goabackend/Makefile.am +index f3b87f1c3e57..588923f88036 100644 +--- a/src/goabackend/Makefile.am ++++ b/src/goabackend/Makefile.am +@@ -91,6 +91,7 @@ libgoa_backend_1_0_la_SOURCES = \ + goawindowsliveprovider.h goawindowsliveprovider.c \ + goatelepathyfactory.h goatelepathyfactory.c \ + goatelepathyprovider.h goatelepathyprovider.c \ ++ goatpaccountlinker.h goatpaccountlinker.c \ + goapocketprovider.h goapocketprovider.c \ + goautils.h goautils.c \ + goawebview.h goawebview.c \ +diff --git a/src/goabackend/goatelepathyprovider.c b/src/goabackend/goatelepathyprovider.c +index 7873607c1382..8a390c82e0c6 100644 +--- a/src/goabackend/goatelepathyprovider.c ++++ b/src/goabackend/goatelepathyprovider.c +@@ -26,6 +26,7 @@ + #include "goaprovider.h" + #include "goaprovider-priv.h" + #include "goatelepathyprovider.h" ++#include "goatpaccountlinker.h" + #include "goautils.h" + + typedef struct _GoaTelepathyProviderPrivate GoaTelepathyProviderPrivate; +@@ -78,6 +79,11 @@ G_DEFINE_TYPE (GoaTelepathyProvider, goa_telepathy_provider, GOA_TYPE_PROVIDER); + + /* ---------------------------------------------------------------------------------------------------- */ + ++static GoaTpAccountLinker *tp_linker = NULL; ++static guint name_watcher_id = 0; ++ ++/* ---------------------------------------------------------------------------------------------------- */ ++ + /* Telepathy / telepathy-account widgets utility functions. */ + + static void +@@ -266,6 +272,38 @@ get_provider_features (GoaProvider *provider) + + /* ---------------------------------------------------------------------------------------------------- */ + ++static void ++on_name_acquired (GDBusConnection *connection, ++ const gchar *name, ++ const gchar *name_owner, ++ gpointer user_data) ++{ ++ tp_linker = goa_tp_account_linker_new (); ++ g_bus_unwatch_name (name_watcher_id); ++ name_watcher_id = 0; ++} ++ ++static void ++initialize (GoaProvider *provider) ++{ ++ static gsize once_init_value = 0; ++ ++ if (g_once_init_enter (&once_init_value)) ++ { ++ name_watcher_id = g_bus_watch_name (G_BUS_TYPE_SESSION, ++ "org.gnome.OnlineAccounts", ++ G_BUS_NAME_WATCHER_FLAGS_NONE, ++ on_name_acquired, ++ NULL, ++ NULL, ++ NULL); ++ ++ g_once_init_leave (&once_init_value, 1); ++ } ++} ++ ++/* ---------------------------------------------------------------------------------------------------- */ ++ + typedef struct + { + GMainLoop *loop; +@@ -1025,6 +1063,7 @@ goa_telepathy_provider_class_init (GoaTelepathyProviderClass *klass) + provider_class->get_provider_icon = get_provider_icon; + provider_class->get_provider_group = get_provider_group; + provider_class->get_provider_features = get_provider_features; ++ provider_class->initialize = initialize; + provider_class->add_account = add_account; + provider_class->refresh_account = refresh_account; + provider_class->build_object = build_object; +diff --git a/src/goabackend/goatpaccountlinker.c b/src/goabackend/goatpaccountlinker.c +new file mode 100644 +index 000000000000..dcdf3f761ca7 +--- /dev/null ++++ b/src/goabackend/goatpaccountlinker.c +@@ -0,0 +1,590 @@ ++/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ ++/* ++ * Copyright (C) 2010-2013 Collabora Ltd. ++ * Copyright (C) 2013 Intel Corporation ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library 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 ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General ++ * Public License along with this library; if not, see . ++ */ ++ ++/* This class makes sure we have a GOA account for each Telepathy account ++ * configured in the system. ++ * Note that this handles only plain Telepathy accounts; the ones with ++ * multiple capabilities (e.g. Facebook) are handled differently. */ ++ ++#include "config.h" ++ ++#include ++#include ++ ++#include "goatpaccountlinker.h" ++#include "goa/goa.h" ++#include "goabackend/goautils.h" ++ ++#define GOA_TP_ACCOUNT_LINKER_GET_PRIVATE(obj) \ ++ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GOA_TYPE_TP_ACCOUNT_LINKER, \ ++ GoaTpAccountLinkerPrivate)) ++ ++G_DEFINE_TYPE (GoaTpAccountLinker, goa_tp_account_linker, G_TYPE_OBJECT) ++ ++struct _GoaTpAccountLinkerPrivate ++{ ++ TpAccountManager *account_manager; ++ GoaClient *goa_client; ++ ++ GHashTable *tp_accounts; /* owned gchar *id -> reffed TpAccount * */ ++ GHashTable *goa_accounts; /* owned gchar *id -> reffed GoaObject * */ ++}; ++ ++/* The path of the Telepathy account is used as common identifier between ++ * GOA and Telepathy */ ++static const gchar * ++get_id_from_tp_account (TpAccount *tp_account) ++{ ++ return tp_proxy_get_object_path (tp_account); ++} ++ ++static const gchar * ++get_id_from_goa_account (GoaAccount *goa_account) ++{ ++ return goa_account_get_identity (goa_account); ++} ++ ++static gboolean ++is_telepathy_account (GoaAccount *goa_account) ++{ ++ const gchar *type = goa_account_get_provider_type (goa_account); ++ return g_str_has_prefix (type, "telepathy/"); ++} ++ ++static void ++goa_account_chat_disabled_changed_cb (GoaAccount *goa_account, ++ GParamSpec *spec, ++ GoaTpAccountLinker *self) ++{ ++ GoaTpAccountLinkerPrivate *priv = self->priv; ++ const gchar *id; ++ TpAccount *tp_account; ++ gboolean tp_enabled; ++ gboolean goa_enabled; ++ ++ id = get_id_from_goa_account (goa_account); ++ tp_account = g_hash_table_lookup (priv->tp_accounts, id); ++ if (tp_account == NULL) ++ return; ++ ++ goa_enabled = !goa_account_get_chat_disabled (goa_account); ++ tp_enabled = tp_account_is_enabled (tp_account); ++ if (tp_enabled != goa_enabled) ++ { ++ g_info ("The GOA account %s (Telepathy object path: %s) has been %s, " ++ "propagating to Telepathy", ++ goa_account_get_id (goa_account), id, ++ goa_enabled ? "enabled" : "disabled"); ++ tp_account_set_enabled_async (tp_account, goa_enabled, NULL, NULL); ++ } ++} ++ ++static void ++tp_account_chat_enabled_changed_cb (TpAccount *tp_account, ++ GParamSpec *spec, ++ GoaTpAccountLinker *self) ++{ ++ GoaTpAccountLinkerPrivate *priv = self->priv; ++ const gchar *id; ++ GoaObject *goa_object; ++ GoaAccount *goa_account; ++ gboolean tp_enabled; ++ gboolean goa_enabled; ++ ++ id = get_id_from_tp_account (tp_account); ++ goa_object = g_hash_table_lookup (priv->goa_accounts, id); ++ if (goa_object == NULL) ++ return; ++ ++ goa_account = goa_object_peek_account (goa_object); ++ goa_enabled = !goa_account_get_chat_disabled (goa_account); ++ tp_enabled = tp_account_is_enabled (tp_account); ++ if (tp_enabled != goa_enabled) ++ { ++ g_info ("The Telepathy account %s has been %s, propagating to GOA", ++ id, tp_enabled ? "enabled" : "disabled"); ++ /* When we set this property, the autogenerated code emits a notify ++ * signal immediately even if the property hasn't changed, so ++ * goa_account_chat_disabled_changed_cb() thinks that the property ++ * changed back to the old value and a cycle starts. ++ * The right notify signal will be emitted later when the property is ++ * actually changed. */ ++ g_signal_handlers_block_by_func (goa_account, ++ goa_account_chat_disabled_changed_cb, self); ++ goa_account_set_chat_disabled (goa_account, !tp_enabled); ++ g_signal_handlers_unblock_by_func (goa_account, ++ goa_account_chat_disabled_changed_cb, self); ++ } ++} ++ ++static void ++goa_account_created_cb (GoaManager *manager, ++ GAsyncResult *res, ++ gpointer user_data) ++{ ++ TpAccount *tp_account = user_data; ++ gchar *goa_account_object_path = NULL; ++ GError *error = NULL; ++ ++ if (!goa_manager_call_add_account_finish (manager, ++ &goa_account_object_path, res, &error)) ++ { ++ g_critical ("Failed to create a GOA account for %s: %s (%s, %d)", ++ get_id_from_tp_account (tp_account), ++ error->message, ++ g_quark_to_string (error->domain), ++ error->code); ++ g_error_free (error); ++ goto out; ++ } ++ ++ g_info ("Created new %s GOA account for Telepathy account %s", ++ goa_account_object_path, get_id_from_tp_account (tp_account)); ++ ++ out: ++ g_object_unref (tp_account); ++} ++ ++static void ++create_goa_account (GoaTpAccountLinker *self, ++ TpAccount *tp_account) ++{ ++ GoaTpAccountLinkerPrivate *priv = self->priv; ++ GVariantBuilder credentials; ++ GVariantBuilder details; ++ gchar *provider; ++ ++ g_info ("Creating new GOA account for Telepathy account %s", ++ get_id_from_tp_account (tp_account)); ++ ++ g_variant_builder_init (&credentials, G_VARIANT_TYPE_VARDICT); ++ ++ g_variant_builder_init (&details, G_VARIANT_TYPE ("a{ss}")); ++ g_variant_builder_add (&details, "{ss}", "ChatEnabled", ++ tp_account_is_enabled (tp_account) ? "true" : "false"); ++ ++ provider = g_strdup_printf ("telepathy/%s", ++ tp_account_get_protocol_name (tp_account)); ++ ++ goa_manager_call_add_account (goa_client_get_manager (priv->goa_client), ++ provider, ++ get_id_from_tp_account (tp_account), ++ tp_account_get_display_name (tp_account), ++ g_variant_builder_end (&credentials), ++ g_variant_builder_end (&details), ++ NULL, /* GCancellable* */ ++ (GAsyncReadyCallback) goa_account_created_cb, ++ g_object_ref (tp_account)); ++ ++ g_free (provider); ++} ++ ++static gboolean ++is_account_filtered (TpAccount *tp_account) ++{ ++ const gchar *env; ++ const gchar *id; ++ ++ env = g_getenv ("GOA_TELEPATHY_DEBUG_ACCOUNT_FILTER"); ++ if (env == NULL || env[0] == '\0') ++ return FALSE; ++ ++ id = get_id_from_tp_account (tp_account); ++ if (g_strstr_len (id, -1, env) != NULL) ++ return FALSE; /* "env" is contained in "id" */ ++ else ++ return TRUE; ++} ++ ++static void ++tp_account_added (GoaTpAccountLinker *self, ++ TpAccount *tp_account) ++{ ++ GoaTpAccountLinkerPrivate *priv = self->priv; ++ const gchar *id = get_id_from_tp_account (tp_account); ++ GoaObject *goa_object = NULL; ++ ++ if (g_strcmp0 (tp_account_get_storage_provider (tp_account), ++ "org.gnome.OnlineAccounts") == 0) ++ { ++ g_debug ("Skipping Telepathy account %s as it's handled directly by GOA", id); ++ return; ++ } ++ ++ if (is_account_filtered (tp_account)) ++ { ++ g_debug ("The account %s is ignored for debugging reasons", id); ++ return; ++ } ++ ++ g_debug ("Telepathy account found: %s", id); ++ ++ g_hash_table_replace (priv->tp_accounts, g_strdup (id), ++ g_object_ref (tp_account)); ++ ++ g_signal_connect_object (tp_account, "notify::enabled", ++ G_CALLBACK (tp_account_chat_enabled_changed_cb), ++ self, 0); ++ ++ goa_object = g_hash_table_lookup (priv->goa_accounts, id); ++ if (goa_object == NULL) ++ { ++ g_debug ("Found a Telepathy account with no corresponding " ++ "GOA account: %s", id); ++ create_goa_account (self, tp_account); ++ } ++ else ++ { ++ g_debug ("Found a Telepathy account with a matching " ++ "GOA account: %s", id); ++ /* Make sure the initial state is synced. */ ++ tp_account_chat_enabled_changed_cb (tp_account, NULL, self); ++ } ++} ++ ++static void ++goa_account_removed_by_us_cb (GObject *object, ++ GAsyncResult *res, ++ gpointer user_data) ++{ ++ /* This callback is only used for debugging */ ++ GoaAccount *goa_account = GOA_ACCOUNT (object); ++ GError *error = NULL; ++ ++ if (!goa_account_call_remove_finish (goa_account, res, &error)) ++ { ++ g_critical ("Error removing GOA account %s (Telepathy object path: %s): " ++ "%s (%s, %d)", ++ goa_account_get_id (goa_account), ++ get_id_from_goa_account (goa_account), ++ error->message, ++ g_quark_to_string (error->domain), ++ error->code); ++ g_error_free (error); ++ } ++} ++ ++static void ++tp_account_removed_cb (TpAccountManager *manager, ++ TpAccount *tp_account, ++ gpointer user_data) ++{ ++ GoaTpAccountLinker *self = user_data; ++ GoaTpAccountLinkerPrivate *priv = self->priv; ++ const gchar *id = get_id_from_tp_account (tp_account); ++ GoaObject *goa_object = NULL; ++ ++ if (!g_hash_table_remove (priv->tp_accounts, id)) ++ { ++ /* 1 - The user removes the GOA account ++ * 2 - We delete the corresponding Telepathy account and remove it ++ * from priv->tp_accounts ++ * 3 - "account-removed" is emitted by the account manager ++ * 4 - tp_account_removed_cb is called for an unknown account ++ */ ++ g_debug ("Ignoring removal of Telepathy account we asked to " ++ "remove (%s)", id); ++ return; ++ } ++ ++ g_info ("Telepathy account %s removed, removing corresponding " ++ "GOA account", id); ++ ++ goa_object = g_hash_table_lookup (priv->goa_accounts, id); ++ if (goa_object == NULL) ++ { ++ g_critical ("There is no GOA account for removed Telepathy " ++ "account %s", id); ++ return; ++ } ++ goa_account_call_remove (goa_object_peek_account (goa_object), ++ NULL, /* cancellable */ ++ goa_account_removed_by_us_cb, NULL); ++ g_hash_table_remove (priv->goa_accounts, id); ++} ++ ++static void ++tp_account_validity_changed_cb (TpAccountManager *manager, ++ TpAccount *tp_account, ++ gboolean valid, ++ gpointer user_data) ++{ ++ GoaTpAccountLinker *self = user_data; ++ ++ if (valid) ++ tp_account_added (self, tp_account); ++} ++ ++static void ++goa_account_added_cb (GoaClient *client, ++ GoaObject *goa_object, ++ gpointer user_data) ++{ ++ GoaTpAccountLinker *self = user_data; ++ GoaTpAccountLinkerPrivate *priv = self->priv; ++ GoaAccount *goa_account = goa_object_peek_account (goa_object); ++ const gchar *id = NULL; ++ TpAccount *tp_account; ++ ++ if (!is_telepathy_account (goa_account)) ++ return; ++ ++ id = get_id_from_goa_account (goa_account); ++ g_debug ("GOA account %s for Telepathy account %s added", ++ goa_account_get_id (goa_account), id); ++ ++ g_signal_connect_object (goa_account, "notify::chat-disabled", ++ G_CALLBACK (goa_account_chat_disabled_changed_cb), self, 0); ++ ++ g_hash_table_insert (priv->goa_accounts, g_strdup (id), ++ g_object_ref (goa_object)); ++ ++ tp_account = g_hash_table_lookup (priv->tp_accounts, id); ++ if (tp_account != NULL) ++ { ++ /* The chat enabled status may have changed during the creation of the ++ * GOA account, so we need to make sure it's synced. */ ++ tp_account_chat_enabled_changed_cb (tp_account, NULL, self); ++ } ++} ++ ++static void ++tp_account_removed_by_us_cb (GObject *object, ++ GAsyncResult *res, ++ gpointer user_data) ++{ ++ /* This callback is only used for debugging */ ++ TpAccount *tp_account = TP_ACCOUNT (object); ++ GError *error = NULL; ++ ++ if (!tp_account_remove_finish (tp_account, res, &error)) ++ { ++ g_critical ("Error removing Telepathy account %s: %s (%s, %d)", ++ get_id_from_tp_account (tp_account), ++ error->message, ++ g_quark_to_string (error->domain), ++ error->code); ++ g_error_free (error); ++ } ++} ++ ++static void ++goa_account_removed_cb (GoaClient *client, ++ GoaObject *goa_object, ++ gpointer user_data) ++{ ++ GoaTpAccountLinker *self = user_data; ++ GoaTpAccountLinkerPrivate *priv = self->priv; ++ GoaAccount *goa_account = goa_object_peek_account (goa_object); ++ const gchar *id = NULL; ++ TpAccount *tp_account = NULL; ++ ++ if (!is_telepathy_account (goa_account)) ++ return; ++ ++ id = get_id_from_goa_account (goa_account); ++ if (!g_hash_table_remove (priv->goa_accounts, id)) ++ { ++ /* 1 - The user removes the Telepathy account (but not the GOA one) ++ * 2 - We delete the corresponding GOA account and remove it ++ * from priv->goa_accounts ++ * 3 - "account-removed" is emitted by the GOA client ++ * 4 - goa_account_removed_cb is called for an unknown account ++ */ ++ g_debug ("Ignoring removal of GOA account we asked to remove " ++ "(%s, Telepathy object path: %s)", ++ goa_account_get_id (goa_account), ++ id); ++ return; ++ } ++ ++ g_info ("GOA account %s for Telepathy account %s removed, " ++ "removing Telepathy account", ++ goa_account_get_id (goa_account), id); ++ ++ tp_account = g_hash_table_lookup (priv->tp_accounts, id); ++ if (tp_account == NULL) ++ { ++ g_critical ("There is no Telepathy account for removed GOA " ++ "account %s (Telepathy object path: %s)", ++ goa_account_get_id (goa_account), id); ++ return; ++ } ++ tp_account_remove_async (tp_account, tp_account_removed_by_us_cb, NULL); ++ g_hash_table_remove (priv->tp_accounts, id); ++} ++ ++static void ++start_if_ready (GoaTpAccountLinker *self) ++{ ++ GoaTpAccountLinkerPrivate *priv = self->priv; ++ GList *goa_accounts = NULL; ++ GList *tp_accounts = NULL; ++ GList *l = NULL; ++ GHashTableIter iter; ++ gpointer key, value; ++ ++ if (priv->goa_client == NULL || ++ priv->account_manager == NULL || ++ !tp_proxy_is_prepared (priv->account_manager, ++ TP_ACCOUNT_MANAGER_FEATURE_CORE)) ++ { ++ /* Not everything is ready yet */ ++ return; ++ } ++ ++ g_debug ("Both GOA and Tp are ready, starting tracking of accounts"); ++ ++ /* GOA */ ++ goa_accounts = goa_client_get_accounts (priv->goa_client); ++ for (l = goa_accounts; l != NULL; l = l->next) ++ goa_account_added_cb (priv->goa_client, l->data, self); ++ g_list_free_full (goa_accounts, g_object_unref); ++ ++ g_signal_connect_object (priv->goa_client, "account-added", ++ G_CALLBACK (goa_account_added_cb), self, 0); ++ g_signal_connect_object (priv->goa_client, "account-removed", ++ G_CALLBACK (goa_account_removed_cb), self, 0); ++ ++ /* Telepathy */ ++ tp_accounts = tp_account_manager_dup_valid_accounts (priv->account_manager); ++ for (l = tp_accounts; l != NULL; l = l->next) ++ tp_account_added (self, l->data); ++ g_list_free_full (tp_accounts, g_object_unref); ++ ++ g_signal_connect_object (priv->account_manager, "account-validity-changed", ++ G_CALLBACK (tp_account_validity_changed_cb), self, 0); ++ g_signal_connect_object (priv->account_manager, "account-removed", ++ G_CALLBACK (tp_account_removed_cb), self, 0); ++ ++ /* Now we check if any Telepathy account was deleted while goa-daemon ++ * was not running. */ ++ g_hash_table_iter_init (&iter, priv->goa_accounts); ++ while (g_hash_table_iter_next (&iter, &key, &value)) ++ { ++ const gchar *id = key; ++ GoaObject *goa_object = value; ++ ++ if (!g_hash_table_lookup (priv->tp_accounts, id)) ++ { ++ g_warning ("The Telepathy account %s was removed while the daemon " ++ "was not running, removing the corresponding GOA account", id); ++ goa_account_call_remove (goa_object_peek_account (goa_object), ++ NULL, /* cancellable */ ++ goa_account_removed_by_us_cb, ++ NULL); /* user data */ ++ } ++ } ++} ++ ++static void ++account_manager_prepared_cb (GObject *object, ++ GAsyncResult *res, ++ gpointer user_data) ++{ ++ GoaTpAccountLinker *self = user_data; ++ GError *error = NULL; ++ ++ if (!tp_proxy_prepare_finish (object, res, &error)) ++ { ++ g_critical ("Error preparing AM: %s", error->message); ++ g_clear_error (&error); ++ return; ++ } ++ ++ g_debug("Telepathy account manager prepared"); ++ start_if_ready (self); ++} ++ ++static void ++goa_client_new_cb (GObject *object, ++ GAsyncResult *result, ++ gpointer user_data) ++{ ++ GoaTpAccountLinker *self = user_data; ++ GoaTpAccountLinkerPrivate *priv = self->priv; ++ GError *error = NULL; ++ ++ priv->goa_client = goa_client_new_finish (result, &error); ++ if (priv->goa_client == NULL) ++ { ++ g_critical ("Error connecting to GOA: %s", error->message); ++ g_clear_error (&error); ++ return; ++ } ++ ++ g_debug("GOA client ready"); ++ start_if_ready (self); ++} ++ ++static void ++goa_tp_account_linker_dispose (GObject *object) ++{ ++ GoaTpAccountLinker *self = GOA_TP_ACCOUNT_LINKER (object); ++ GoaTpAccountLinkerPrivate *priv = self->priv; ++ ++ g_clear_object (&priv->account_manager); ++ g_clear_object (&priv->goa_client); ++ ++ g_clear_pointer (&priv->goa_accounts, g_hash_table_unref); ++ g_clear_pointer (&priv->tp_accounts, g_hash_table_unref); ++ ++ G_OBJECT_CLASS (goa_tp_account_linker_parent_class)->dispose (object); ++} ++ ++static void ++goa_tp_account_linker_init (GoaTpAccountLinker *self) ++{ ++ GoaTpAccountLinkerPrivate *priv; ++ ++ g_debug ("Starting GOA <-> Telepathy account linker"); ++ ++ self->priv = GOA_TP_ACCOUNT_LINKER_GET_PRIVATE (self); ++ priv = self->priv; ++ ++ priv->goa_accounts = g_hash_table_new_full (g_str_hash, g_str_equal, ++ g_free, g_object_unref); ++ priv->tp_accounts = g_hash_table_new_full (g_str_hash, g_str_equal, ++ g_free, g_object_unref); ++ ++ priv->account_manager = tp_account_manager_dup (); ++ tp_proxy_prepare_async (priv->account_manager, NULL, ++ account_manager_prepared_cb, self); ++ ++ goa_client_new (NULL, goa_client_new_cb, self); ++} ++ ++static void ++goa_tp_account_linker_class_init (GoaTpAccountLinkerClass *klass) ++{ ++ GObjectClass *gobject_class = G_OBJECT_CLASS (klass); ++ ++ goa_utils_initialize_client_factory (); ++ ++ g_type_class_add_private (gobject_class, ++ sizeof (GoaTpAccountLinkerPrivate)); ++ ++ gobject_class->dispose = goa_tp_account_linker_dispose; ++} ++ ++GoaTpAccountLinker * ++goa_tp_account_linker_new (void) ++{ ++ return g_object_new (GOA_TYPE_TP_ACCOUNT_LINKER, NULL); ++} +diff --git a/src/goabackend/goatpaccountlinker.h b/src/goabackend/goatpaccountlinker.h +new file mode 100644 +index 000000000000..3f5b12955df0 +--- /dev/null ++++ b/src/goabackend/goatpaccountlinker.h +@@ -0,0 +1,54 @@ ++/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ ++/* ++ * Copyright (C) 2010-2013 Collabora Ltd. ++ * Copyright (C) 2013 Intel Corporation ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2 of the License, or (at your option) any later version. ++ * ++ * This library 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 ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General ++ * Public License along with this library; if not, see . ++ */ ++ ++#ifndef __GOA_TP_ACCOUNT_LINKER_H__ ++#define __GOA_TP_ACCOUNT_LINKER_H__ ++ ++#include ++ ++G_BEGIN_DECLS ++ ++#define GOA_TYPE_TP_ACCOUNT_LINKER (goa_tp_account_linker_get_type ()) ++#define GOA_TP_ACCOUNT_LINKER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOA_TYPE_TP_ACCOUNT_LINKER, GoaTpAccountLinker)) ++#define GOA_TP_ACCOUNT_LINKER_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST ((obj), GOA_TYPE_TP_ACCOUNT_LINKER, GoaTpAccountLinkerClass)) ++#define GOA_IS_TP_ACCOUNT_LINKER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GOA_TYPE_TP_ACCOUNT_LINKER)) ++#define GOA_IS_TP_ACCOUNT_LINKER_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((obj), GOA_TYPE_TP_ACCOUNT_LINKER)) ++#define GOA_TP_ACCOUNT_LINKER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GOA_TYPE_TP_ACCOUNT_LINKER, GoaTpAccountLinkerClass)) ++ ++typedef struct _GoaTpAccountLinker GoaTpAccountLinker; ++typedef struct _GoaTpAccountLinkerClass GoaTpAccountLinkerClass; ++typedef struct _GoaTpAccountLinkerPrivate GoaTpAccountLinkerPrivate; ++ ++struct _GoaTpAccountLinker ++{ ++ GObject parent_instance; ++ GoaTpAccountLinkerPrivate *priv; ++}; ++ ++struct _GoaTpAccountLinkerClass ++{ ++ GObjectClass parent_class; ++}; ++ ++GType goa_tp_account_linker_get_type (void) G_GNUC_CONST; ++GoaTpAccountLinker *goa_tp_account_linker_new (void); ++ ++G_END_DECLS ++ ++#endif +-- +2.5.5 + + +From d26e6f3c6ec826ec16aaa298eaf3cca66bab33f1 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Wed, 1 Jun 2016 19:53:44 +0200 +Subject: [PATCH 21/22] tplinker: Shuffle some code around + +This will make the subsequent commit easier to read. + +https://bugzilla.gnome.org/show_bug.cgi?id=766733 +--- + src/goabackend/goatpaccountlinker.c | 40 ++++++++++++++++++------------------- + 1 file changed, 20 insertions(+), 20 deletions(-) + +diff --git a/src/goabackend/goatpaccountlinker.c b/src/goabackend/goatpaccountlinker.c +index dcdf3f761ca7..71255ec6cff9 100644 +--- a/src/goabackend/goatpaccountlinker.c ++++ b/src/goabackend/goatpaccountlinker.c +@@ -68,6 +68,26 @@ is_telepathy_account (GoaAccount *goa_account) + } + + static void ++tp_account_removed_by_us_cb (GObject *object, ++ GAsyncResult *res, ++ gpointer user_data) ++{ ++ /* This callback is only used for debugging */ ++ TpAccount *tp_account = TP_ACCOUNT (object); ++ GError *error = NULL; ++ ++ if (!tp_account_remove_finish (tp_account, res, &error)) ++ { ++ g_critical ("Error removing Telepathy account %s: %s (%s, %d)", ++ get_id_from_tp_account (tp_account), ++ error->message, ++ g_quark_to_string (error->domain), ++ error->code); ++ g_error_free (error); ++ } ++} ++ ++static void + goa_account_chat_disabled_changed_cb (GoaAccount *goa_account, + GParamSpec *spec, + GoaTpAccountLinker *self) +@@ -365,26 +385,6 @@ goa_account_added_cb (GoaClient *client, + } + + static void +-tp_account_removed_by_us_cb (GObject *object, +- GAsyncResult *res, +- gpointer user_data) +-{ +- /* This callback is only used for debugging */ +- TpAccount *tp_account = TP_ACCOUNT (object); +- GError *error = NULL; +- +- if (!tp_account_remove_finish (tp_account, res, &error)) +- { +- g_critical ("Error removing Telepathy account %s: %s (%s, %d)", +- get_id_from_tp_account (tp_account), +- error->message, +- g_quark_to_string (error->domain), +- error->code); +- g_error_free (error); +- } +-} +- +-static void + goa_account_removed_cb (GoaClient *client, + GoaObject *goa_object, + gpointer user_data) +-- +2.5.5 + + +From d73bb711099d6c24e7cef82de43dda2747d7d6c3 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Wed, 1 Jun 2016 20:00:08 +0200 +Subject: [PATCH 22/22] telepathy: Use GoaProvider:remove_account for deleting + the TpAccount + +... instead of listening to GoaClient::account-removed. + +API was added to GoaTpAccountLinker to explicitly request the removal +of the TpAccount. This is used by GoaTelepathyProvider in its +GoaProvider:remove_account implementation. + +https://bugzilla.gnome.org/show_bug.cgi?id=766733 +--- + src/goabackend/goatelepathyprovider.c | 63 ++++++++++++ + src/goabackend/goatpaccountlinker.c | 178 ++++++++++++++++++++++++---------- + src/goabackend/goatpaccountlinker.h | 10 ++ + 3 files changed, 200 insertions(+), 51 deletions(-) + +diff --git a/src/goabackend/goatelepathyprovider.c b/src/goabackend/goatelepathyprovider.c +index 8a390c82e0c6..3d76080d0751 100644 +--- a/src/goabackend/goatelepathyprovider.c ++++ b/src/goabackend/goatelepathyprovider.c +@@ -787,6 +787,67 @@ out: + + /* ---------------------------------------------------------------------------------------------------- */ + ++static void ++remove_account_remove_tp_account_cb (GObject *source_object, ++ GAsyncResult *res, ++ gpointer user_data) ++{ ++ GError *error; ++ GTask *task = G_TASK (user_data); ++ ++ error = NULL; ++ if (!goa_tp_account_linker_remove_tp_account_finish (tp_linker, res, &error)) ++ { ++ g_task_return_error (task, error); ++ goto out; ++ } ++ ++ g_task_return_boolean (task, TRUE); ++ ++ out: ++ g_object_unref (task); ++} ++ ++static void ++remove_account (GoaProvider *provider, ++ GoaObject *object, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data) ++{ ++ GoaTelepathyProvider *self = GOA_TELEPATHY_PROVIDER (provider); ++ GTask *task; ++ ++ task = g_task_new (self, cancellable, callback, user_data); ++ g_task_set_source_tag (task, remove_account); ++ ++ goa_tp_account_linker_remove_tp_account (tp_linker, ++ object, ++ cancellable, ++ remove_account_remove_tp_account_cb, ++ g_object_ref (task)); ++ ++ g_object_unref (task); ++} ++ ++static gboolean ++remove_account_finish (GoaProvider *provider, ++ GAsyncResult *res, ++ GError **error) ++{ ++ GoaTelepathyProvider *self = GOA_TELEPATHY_PROVIDER (provider); ++ GTask *task; ++ ++ g_return_val_if_fail (g_task_is_valid (res, self), FALSE); ++ task = G_TASK (res); ++ ++ g_warn_if_fail (g_task_get_source_tag (task) == remove_account); ++ ++ return g_task_propagate_boolean (task, error); ++} ++ ++/* ---------------------------------------------------------------------------------------------------- */ ++ + typedef struct + { + guint ref_count; +@@ -1067,6 +1128,8 @@ goa_telepathy_provider_class_init (GoaTelepathyProviderClass *klass) + provider_class->add_account = add_account; + provider_class->refresh_account = refresh_account; + provider_class->build_object = build_object; ++ provider_class->remove_account = remove_account; ++ provider_class->remove_account_finish = remove_account_finish; + provider_class->show_account = show_account; + + g_type_class_add_private (object_class, sizeof (GoaTelepathyProviderPrivate)); +diff --git a/src/goabackend/goatpaccountlinker.c b/src/goabackend/goatpaccountlinker.c +index 71255ec6cff9..aa9f01e839c0 100644 +--- a/src/goabackend/goatpaccountlinker.c ++++ b/src/goabackend/goatpaccountlinker.c +@@ -28,7 +28,6 @@ + #include + + #include "goatpaccountlinker.h" +-#include "goa/goa.h" + #include "goabackend/goautils.h" + + #define GOA_TP_ACCOUNT_LINKER_GET_PRIVATE(obj) \ +@@ -44,6 +43,8 @@ struct _GoaTpAccountLinkerPrivate + + GHashTable *tp_accounts; /* owned gchar *id -> reffed TpAccount * */ + GHashTable *goa_accounts; /* owned gchar *id -> reffed GoaObject * */ ++ ++ GQueue *remove_tp_account_queue; + }; + + /* The path of the Telepathy account is used as common identifier between +@@ -72,9 +73,9 @@ tp_account_removed_by_us_cb (GObject *object, + GAsyncResult *res, + gpointer user_data) + { +- /* This callback is only used for debugging */ + TpAccount *tp_account = TP_ACCOUNT (object); + GError *error = NULL; ++ GTask *task = G_TASK (user_data); + + if (!tp_account_remove_finish (tp_account, res, &error)) + { +@@ -83,8 +84,80 @@ tp_account_removed_by_us_cb (GObject *object, + error->message, + g_quark_to_string (error->domain), + error->code); +- g_error_free (error); ++ g_task_return_error (task, error); ++ goto out; ++ } ++ ++ g_task_return_boolean (task, TRUE); ++ ++ out: ++ g_object_unref (task); ++} ++ ++static void ++remove_tp_account_queue_check (GoaTpAccountLinker *self) ++{ ++ GoaTpAccountLinkerPrivate *priv = self->priv; ++ GList *l; ++ ++ if (priv->goa_client == NULL || ++ priv->account_manager == NULL || ++ !tp_proxy_is_prepared (priv->account_manager, TP_ACCOUNT_MANAGER_FEATURE_CORE)) ++ { ++ /* Not everything is ready yet */ ++ return; ++ } ++ ++ if (priv->remove_tp_account_queue->length == 0) ++ return; ++ ++ for (l = priv->remove_tp_account_queue->head; l != NULL; l = l->next) ++ { ++ GTask *task = G_TASK (l->data); ++ GoaAccount *goa_account; ++ GoaObject *goa_object; ++ TpAccount *tp_account; ++ const gchar *id; ++ ++ goa_object = GOA_OBJECT (g_task_get_task_data (task)); ++ goa_account = goa_object_peek_account (goa_object); ++ ++ id = get_id_from_goa_account (goa_account); ++ if (!g_hash_table_remove (priv->goa_accounts, id)) ++ { ++ /* 1 - The user removes the Telepathy account (but not the GOA one) ++ * 2 - We delete the corresponding GOA account and remove it ++ * from priv->goa_accounts ++ * 3 - The Telepathy provider again tries to remove the ++ * corresponding Telepathy account ++ */ ++ g_debug ("Ignoring removal of GOA account we asked to remove " ++ "(%s, Telepathy object path: %s)", ++ goa_account_get_id (goa_account), ++ id); ++ g_task_return_boolean (task, TRUE); ++ continue; ++ } ++ ++ g_info ("GOA account %s for Telepathy account %s removed, " ++ "removing Telepathy account", ++ goa_account_get_id (goa_account), id); ++ ++ tp_account = g_hash_table_lookup (priv->tp_accounts, id); ++ if (tp_account == NULL) ++ { ++ g_critical ("There is no Telepathy account for removed GOA " ++ "account %s (Telepathy object path: %s)", ++ goa_account_get_id (goa_account), id); ++ g_task_return_boolean (task, TRUE); ++ continue; ++ } ++ tp_account_remove_async (tp_account, tp_account_removed_by_us_cb, g_object_ref (task)); ++ g_hash_table_remove (priv->tp_accounts, id); + } ++ ++ g_queue_foreach (priv->remove_tp_account_queue, (GFunc) g_object_unref, NULL); ++ g_queue_clear (priv->remove_tp_account_queue); + } + + static void +@@ -385,52 +458,6 @@ goa_account_added_cb (GoaClient *client, + } + + static void +-goa_account_removed_cb (GoaClient *client, +- GoaObject *goa_object, +- gpointer user_data) +-{ +- GoaTpAccountLinker *self = user_data; +- GoaTpAccountLinkerPrivate *priv = self->priv; +- GoaAccount *goa_account = goa_object_peek_account (goa_object); +- const gchar *id = NULL; +- TpAccount *tp_account = NULL; +- +- if (!is_telepathy_account (goa_account)) +- return; +- +- id = get_id_from_goa_account (goa_account); +- if (!g_hash_table_remove (priv->goa_accounts, id)) +- { +- /* 1 - The user removes the Telepathy account (but not the GOA one) +- * 2 - We delete the corresponding GOA account and remove it +- * from priv->goa_accounts +- * 3 - "account-removed" is emitted by the GOA client +- * 4 - goa_account_removed_cb is called for an unknown account +- */ +- g_debug ("Ignoring removal of GOA account we asked to remove " +- "(%s, Telepathy object path: %s)", +- goa_account_get_id (goa_account), +- id); +- return; +- } +- +- g_info ("GOA account %s for Telepathy account %s removed, " +- "removing Telepathy account", +- goa_account_get_id (goa_account), id); +- +- tp_account = g_hash_table_lookup (priv->tp_accounts, id); +- if (tp_account == NULL) +- { +- g_critical ("There is no Telepathy account for removed GOA " +- "account %s (Telepathy object path: %s)", +- goa_account_get_id (goa_account), id); +- return; +- } +- tp_account_remove_async (tp_account, tp_account_removed_by_us_cb, NULL); +- g_hash_table_remove (priv->tp_accounts, id); +-} +- +-static void + start_if_ready (GoaTpAccountLinker *self) + { + GoaTpAccountLinkerPrivate *priv = self->priv; +@@ -459,8 +486,6 @@ start_if_ready (GoaTpAccountLinker *self) + + g_signal_connect_object (priv->goa_client, "account-added", + G_CALLBACK (goa_account_added_cb), self, 0); +- g_signal_connect_object (priv->goa_client, "account-removed", +- G_CALLBACK (goa_account_removed_cb), self, 0); + + /* Telepathy */ + tp_accounts = tp_account_manager_dup_valid_accounts (priv->account_manager); +@@ -491,6 +516,8 @@ start_if_ready (GoaTpAccountLinker *self) + NULL); /* user data */ + } + } ++ ++ remove_tp_account_queue_check (self); + } + + static void +@@ -539,6 +566,12 @@ goa_tp_account_linker_dispose (GObject *object) + GoaTpAccountLinker *self = GOA_TP_ACCOUNT_LINKER (object); + GoaTpAccountLinkerPrivate *priv = self->priv; + ++ if (priv->remove_tp_account_queue != NULL) ++ { ++ g_queue_free_full (priv->remove_tp_account_queue, g_object_unref); ++ priv->remove_tp_account_queue = NULL; ++ } ++ + g_clear_object (&priv->account_manager); + g_clear_object (&priv->goa_client); + +@@ -563,6 +596,8 @@ goa_tp_account_linker_init (GoaTpAccountLinker *self) + priv->tp_accounts = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, g_object_unref); + ++ priv->remove_tp_account_queue = g_queue_new (); ++ + priv->account_manager = tp_account_manager_dup (); + tp_proxy_prepare_async (priv->account_manager, NULL, + account_manager_prepared_cb, self); +@@ -588,3 +623,44 @@ goa_tp_account_linker_new (void) + { + return g_object_new (GOA_TYPE_TP_ACCOUNT_LINKER, NULL); + } ++ ++void ++goa_tp_account_linker_remove_tp_account (GoaTpAccountLinker *self, ++ GoaObject *object, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data) ++{ ++ GoaTpAccountLinkerPrivate *priv; ++ GTask *task; ++ ++ g_return_if_fail (GOA_IS_TP_ACCOUNT_LINKER (self)); ++ priv = self->priv; ++ ++ g_return_if_fail (GOA_IS_OBJECT (object)); ++ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); ++ ++ task = g_task_new (self, cancellable, callback, user_data); ++ g_task_set_source_tag (task, goa_tp_account_linker_remove_tp_account); ++ g_task_set_task_data (task, g_object_ref (object), g_object_unref); ++ g_queue_push_tail (priv->remove_tp_account_queue, g_object_ref (task)); ++ ++ remove_tp_account_queue_check (self); ++ ++ g_object_unref (task); ++} ++ ++gboolean ++goa_tp_account_linker_remove_tp_account_finish (GoaTpAccountLinker *self, ++ GAsyncResult *res, ++ GError **error) ++{ ++ GTask *task; ++ ++ g_return_val_if_fail (g_task_is_valid (res, self), FALSE); ++ task = G_TASK (res); ++ ++ g_warn_if_fail (g_task_get_source_tag (task) == goa_tp_account_linker_remove_tp_account); ++ ++ return g_task_propagate_boolean (task, error); ++} +diff --git a/src/goabackend/goatpaccountlinker.h b/src/goabackend/goatpaccountlinker.h +index 3f5b12955df0..8c7efd8a956e 100644 +--- a/src/goabackend/goatpaccountlinker.h ++++ b/src/goabackend/goatpaccountlinker.h +@@ -22,6 +22,8 @@ + + #include + ++#include "goa/goa.h" ++ + G_BEGIN_DECLS + + #define GOA_TYPE_TP_ACCOUNT_LINKER (goa_tp_account_linker_get_type ()) +@@ -48,6 +50,14 @@ struct _GoaTpAccountLinkerClass + + GType goa_tp_account_linker_get_type (void) G_GNUC_CONST; + GoaTpAccountLinker *goa_tp_account_linker_new (void); ++void goa_tp_account_linker_remove_tp_account (GoaTpAccountLinker *self, ++ GoaObject *object, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data); ++gboolean goa_tp_account_linker_remove_tp_account_finish (GoaTpAccountLinker *self, ++ GAsyncResult *res, ++ GError **error); + + G_END_DECLS + +-- +2.5.5 + diff --git a/SOURCES/telepathy-account-widgets-update-submodule.patch b/SOURCES/telepathy-account-widgets-update-submodule.patch new file mode 100644 index 0000000..05c1994 --- /dev/null +++ b/SOURCES/telepathy-account-widgets-update-submodule.patch @@ -0,0 +1,29 @@ +diff -urNp gnome-online-accounts-3.14.5.orig/telepathy-account-widgets/tp-account-widgets/tpaw-account-widget.c gnome-online-accounts-3.14.5/telepathy-account-widgets/tp-account-widgets/tpaw-account-widget.c +--- gnome-online-accounts-3.14.5.orig/telepathy-account-widgets/tp-account-widgets/tpaw-account-widget.c 2016-03-14 14:10:33.000000000 +0100 ++++ gnome-online-accounts-3.14.5/telepathy-account-widgets/tp-account-widgets/tpaw-account-widget.c 2016-06-10 16:31:03.000000000 +0200 +@@ -565,6 +565,9 @@ tpaw_account_widget_setup_widget (TpawAc + + if (strstr (param_name, "password")) + { ++ if (self->priv->dialog != NULL) ++ gtk_entry_set_activates_default (GTK_ENTRY (widget), TRUE); ++ + gtk_entry_set_visibility (GTK_ENTRY (widget), FALSE); + + /* Add 'clear' icon */ +@@ -582,8 +585,13 @@ tpaw_account_widget_setup_widget (TpawAc + G_CALLBACK (password_entry_activated_cb), self); + } + else if (strstr (param_name, "account")) +- g_signal_connect (widget, "activate", +- G_CALLBACK (account_entry_activated_cb), self); ++ { ++ if (self->priv->dialog != NULL) ++ gtk_entry_set_activates_default (GTK_ENTRY (widget), TRUE); ++ ++ g_signal_connect (widget, "activate", ++ G_CALLBACK (account_entry_activated_cb), self); ++ } + + g_signal_connect (widget, "changed", + G_CALLBACK (account_widget_entry_changed_cb), self); diff --git a/SOURCES/temporary-accounts-clean-up.patch b/SOURCES/temporary-accounts-clean-up.patch new file mode 100644 index 0000000..537dc77 --- /dev/null +++ b/SOURCES/temporary-accounts-clean-up.patch @@ -0,0 +1,1049 @@ +From 1d87daa346e054a13e8e6d78986981b4532867f1 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Fri, 22 Jan 2016 17:27:58 +0100 +Subject: [PATCH 01/11] Use g_clear_pointer wherever applicable + +--- + src/daemon/goadaemon.c | 7 ++----- + src/daemon/main.c | 6 ++---- + src/goabackend/goaexchangeprovider.c | 6 ++---- + src/goabackend/goaimapsmtpprovider.c | 9 +++------ + src/goabackend/goakerberosprovider.c | 8 ++------ + src/goabackend/goamediaserverprovider.c | 6 ++---- + src/goabackend/goaoauth2provider.c | 3 +-- + src/goabackend/goaoauthprovider.c | 9 +++------ + src/goabackend/goaowncloudprovider.c | 6 ++---- + 9 files changed, 19 insertions(+), 41 deletions(-) + +diff --git a/src/daemon/goadaemon.c b/src/daemon/goadaemon.c +index 1a7b1fff65b5..12dadbbf54f2 100644 +--- a/src/daemon/goadaemon.c ++++ b/src/daemon/goadaemon.c +@@ -934,9 +934,7 @@ get_all_providers_cb (GObject *source, + g_free (group); + g_free (id); + g_free (path); +- if (key_file != NULL) +- g_key_file_free (key_file); +- ++ g_clear_pointer (&key_file, (GDestroyNotify) g_key_file_free); + g_object_unref (data->daemon); + g_object_unref (data->manager); + g_object_unref (data->invocation); +@@ -1087,8 +1085,7 @@ on_account_handle_remove (GoaAccount *account, + out: + g_clear_object (&provider); + g_free (data); +- if (key_file != NULL) +- g_key_file_free (key_file); ++ g_clear_pointer (&key_file, (GDestroyNotify) g_key_file_free); + g_free (group); + g_free (path); + return TRUE; /* invocation was handled */ +diff --git a/src/daemon/main.c b/src/daemon/main.c +index fd3242e94380..a04cc3992a83 100644 +--- a/src/daemon/main.c ++++ b/src/daemon/main.c +@@ -135,10 +135,8 @@ main (int argc, + g_object_unref (tp_linker); + if (name_owner_id != 0) + g_bus_unown_name (name_owner_id); +- if (loop != NULL) +- g_main_loop_unref (loop); +- if (opt_context != NULL) +- g_option_context_free (opt_context); ++ g_clear_pointer (&loop, (GDestroyNotify) g_main_loop_unref); ++ g_clear_pointer (&opt_context, (GDestroyNotify) g_option_context_free); + + g_message ("goa-daemon version %s exiting", PACKAGE_VERSION); + +diff --git a/src/goabackend/goaexchangeprovider.c b/src/goabackend/goaexchangeprovider.c +index 78191e3c5678..923fb6563f5d 100644 +--- a/src/goabackend/goaexchangeprovider.c ++++ b/src/goabackend/goaexchangeprovider.c +@@ -754,8 +754,7 @@ add_account (GoaProvider *provider, + g_assert (ret != NULL); + + g_free (data.account_object_path); +- if (data.loop != NULL) +- g_main_loop_unref (data.loop); ++ g_clear_pointer (&data.loop, (GDestroyNotify) g_main_loop_unref); + g_clear_object (&data.cancellable); + if (ews_client != NULL) + g_object_unref (ews_client); +@@ -909,8 +908,7 @@ refresh_account (GoaProvider *provider, + g_propagate_error (error, data.error); + + gtk_widget_destroy (dialog); +- if (data.loop != NULL) +- g_main_loop_unref (data.loop); ++ g_clear_pointer (&data.loop, (GDestroyNotify) g_main_loop_unref); + g_clear_object (&data.cancellable); + if (ews_client != NULL) + g_object_unref (ews_client); +diff --git a/src/goabackend/goaimapsmtpprovider.c b/src/goabackend/goaimapsmtpprovider.c +index 9c609cbe440f..4e41a6449c43 100644 +--- a/src/goabackend/goaimapsmtpprovider.c ++++ b/src/goabackend/goaimapsmtpprovider.c +@@ -489,8 +489,7 @@ ensure_credentials_sync (GoaProvider *provider, + g_free (smtp_password); + g_free (smtp_server); + g_free (smtp_username); +- if (credentials != NULL) +- g_variant_unref (credentials); ++ g_clear_pointer (&credentials, (GDestroyNotify) g_variant_unref); + return ret; + } + +@@ -1203,8 +1202,7 @@ add_account (GoaProvider *provider, + + g_free (domain); + g_free (data.account_object_path); +- if (data.loop != NULL) +- g_main_loop_unref (data.loop); ++ g_clear_pointer (&data.loop, (GDestroyNotify) g_main_loop_unref); + g_clear_object (&data.cancellable); + g_clear_object (&imap_auth); + g_clear_object (&smtp_auth); +@@ -1488,8 +1486,7 @@ refresh_account (GoaProvider *provider, + g_free (imap_username); + g_free (smtp_server); + g_free (smtp_username); +- if (data.loop != NULL) +- g_main_loop_unref (data.loop); ++ g_clear_pointer (&data.loop, (GDestroyNotify) g_main_loop_unref); + g_clear_object (&data.cancellable); + g_clear_object (&imap_auth); + g_clear_object (&smtp_auth); +diff --git a/src/goabackend/goakerberosprovider.c b/src/goabackend/goakerberosprovider.c +index 69a1c9142466..a3a9bd9f5369 100644 +--- a/src/goabackend/goakerberosprovider.c ++++ b/src/goabackend/goakerberosprovider.c +@@ -358,10 +358,7 @@ get_ticket_sync (GoaKerberosProvider *self, + out: + g_clear_object (&ticketing); + g_free (object_path); +- +- if (credentials != NULL) +- g_variant_unref (credentials); +- ++ g_clear_pointer (&credentials, (GDestroyNotify) g_variant_unref); + return ret; + } + +@@ -1315,8 +1312,7 @@ start_over: + g_free (request.account_object_path); + g_free (principal); + g_free (principal_for_display); +- if (request.loop != NULL) +- g_main_loop_unref (request.loop); ++ g_clear_pointer (&request.loop, (GDestroyNotify) g_main_loop_unref); + return object; + } + +diff --git a/src/goabackend/goamediaserverprovider.c b/src/goabackend/goamediaserverprovider.c +index eded24c256bc..860fe1588043 100644 +--- a/src/goabackend/goamediaserverprovider.c ++++ b/src/goabackend/goamediaserverprovider.c +@@ -216,8 +216,7 @@ ensure_credentials_sync (GoaProvider *provider, + ret = TRUE; + + out: +- if (credentials != NULL) +- g_variant_unref (credentials); ++ g_clear_pointer (&credentials, (GDestroyNotify) g_variant_unref); + return ret; + } + +@@ -529,8 +528,7 @@ add_account (GoaProvider *provider, + g_free (data.account_object_path); + g_free (data.friendly_name); + g_free (data.udn); +- if (data.loop != NULL) +- g_main_loop_unref (data.loop); ++ g_clear_pointer (&data.loop, (GDestroyNotify) g_main_loop_unref); + return ret; + } + +diff --git a/src/goabackend/goaoauth2provider.c b/src/goabackend/goaoauth2provider.c +index 2980c470384d..4e6f185c5c32 100644 +--- a/src/goabackend/goaoauth2provider.c ++++ b/src/goabackend/goaoauth2provider.c +@@ -1592,8 +1592,7 @@ goa_oauth2_provider_get_access_token_sync (GoaOAuth2Provider *provider, + g_free (refresh_token); + g_free (old_refresh_token); + g_free (password); +- if (credentials != NULL) +- g_variant_unref (credentials); ++ g_clear_pointer (&credentials, (GDestroyNotify) g_variant_unref); + + g_mutex_unlock (lock); + +diff --git a/src/goabackend/goaoauthprovider.c b/src/goabackend/goaoauthprovider.c +index 6225affbf754..2cd9b472e067 100644 +--- a/src/goabackend/goaoauthprovider.c ++++ b/src/goabackend/goaoauthprovider.c +@@ -991,8 +991,7 @@ get_tokens_and_identity (GoaOAuthProvider *provider, + g_free (url); + + g_free (data.oauth_verifier); +- if (data.loop != NULL) +- g_main_loop_unref (data.loop); ++ g_clear_pointer (&data.loop, (GDestroyNotify) g_main_loop_unref); + g_free (data.access_token); + g_free (data.access_token_secret); + g_free (escaped_request_token); +@@ -1170,8 +1169,7 @@ goa_oauth_provider_add_account (GoaProvider *_provider, + g_free (access_token_secret); + g_free (session_handle); + g_free (data.account_object_path); +- if (data.loop != NULL) +- g_main_loop_unref (data.loop); ++ g_clear_pointer (&data.loop, (GDestroyNotify) g_main_loop_unref); + return ret; + } + +@@ -1544,8 +1542,7 @@ goa_oauth_provider_get_access_token_sync (GoaOAuthProvider *provider, + g_free (access_token_secret_for_refresh); + g_free (session_handle_for_refresh); + g_free (password); +- if (credentials != NULL) +- g_variant_unref (credentials); ++ g_clear_pointer (&credentials, (GDestroyNotify) g_variant_unref); + + g_mutex_unlock (lock); + +diff --git a/src/goabackend/goaowncloudprovider.c b/src/goabackend/goaowncloudprovider.c +index 5b408adeb397..e202e05770b9 100644 +--- a/src/goabackend/goaowncloudprovider.c ++++ b/src/goabackend/goaowncloudprovider.c +@@ -919,8 +919,7 @@ add_account (GoaProvider *provider, + g_free (server); + g_free (uri); + g_free (data.account_object_path); +- if (data.loop != NULL) +- g_main_loop_unref (data.loop); ++ g_clear_pointer (&data.loop, (GDestroyNotify) g_main_loop_unref); + g_clear_object (&data.cancellable); + g_clear_object (&http_client); + return ret; +@@ -1076,8 +1075,7 @@ refresh_account (GoaProvider *provider, + gtk_widget_destroy (dialog); + g_free (uri); + g_free (uri_webdav); +- if (data.loop != NULL) +- g_main_loop_unref (data.loop); ++ g_clear_pointer (&data.loop, (GDestroyNotify) g_main_loop_unref); + g_clear_object (&data.cancellable); + g_clear_object (&http_client); + return ret; +-- +2.5.5 + + +From 2fa0c6a91224c68411c67a69dfaa15a5e50a4848 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Wed, 4 May 2016 16:59:28 +0200 +Subject: [PATCH 02/11] daemon, utils: Simplify saving a GKeyFile to a path + +We can now use g_key_file_save_to_file which wraps g_key_file_to_data +and g_file_set_contents. + +At the moment, g_key_file_to_data is documented as never throwing an +error. So we don't lose anything in terms of error reporting. Even if +this changes in the future, I think we can live without a separate +error message for g_key_file_to_data. + +Bump minimum GLib version to 2.40. + +https://bugzilla.gnome.org/show_bug.cgi?id=688041 +--- + configure.ac | 2 +- + src/daemon/goadaemon.c | 37 ++----------------------------------- + src/goabackend/goautils.c | 24 +++--------------------- + 3 files changed, 6 insertions(+), 57 deletions(-) + +diff --git a/configure.ac b/configure.ac +index a76ce9770d96..e6c78588394e 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -82,7 +82,7 @@ GTK_DOC_CHECK([1.3]) + # Libraries + # + +-PKG_CHECK_MODULES(GLIB, [glib-2.0 gio-2.0 gio-unix-2.0 >= 2.35]) ++PKG_CHECK_MODULES(GLIB, [glib-2.0 gio-2.0 gio-unix-2.0 >= 2.40]) + AC_SUBST(GLIB_CFLAGS) + AC_SUBST(GLIB_LIBS) + +diff --git a/src/daemon/goadaemon.c b/src/daemon/goadaemon.c +index 12dadbbf54f2..67f43151ea7c 100644 +--- a/src/daemon/goadaemon.c ++++ b/src/daemon/goadaemon.c +@@ -890,23 +890,8 @@ get_all_providers_cb (GObject *source, + g_key_file_set_string (key_file, group, key, value); + } + +- g_free (key_file_data); +- error = NULL; +- key_file_data = g_key_file_to_data (key_file, +- &length, +- &error); +- if (key_file_data == NULL) +- { +- g_prefix_error (&error, "Error generating key-value-file: "); +- g_dbus_method_invocation_take_error (data->invocation, error); +- goto out; +- } +- + error = NULL; +- if (!g_file_set_contents (path, +- key_file_data, +- length, +- &error)) ++ if (!g_key_file_save_to_file (key_file, path, &error)) + { + g_prefix_error (&error, "Error writing key-value-file %s: ", path); + g_dbus_method_invocation_take_error (data->invocation, error); +@@ -987,8 +972,6 @@ on_account_handle_remove (GoaAccount *account, + const gchar *provider_type; + gchar *path; + gchar *group; +- gchar *data; +- gsize length; + GError *error; + + provider = NULL; +@@ -996,7 +979,6 @@ on_account_handle_remove (GoaAccount *account, + path = NULL; + group = NULL; + key_file = NULL; +- data = NULL; + + /* update key-file - right now we only support removing the account + * if the entry is in ~/.config/goa-1.0/accounts.conf +@@ -1025,21 +1007,7 @@ on_account_handle_remove (GoaAccount *account, + } + + error = NULL; +- data = g_key_file_to_data (key_file, +- &length, +- &error); +- if (data == NULL) +- { +- g_prefix_error (&error, "Error generating key-value-file: "); +- g_dbus_method_invocation_take_error (invocation, error); +- goto out; +- } +- +- error = NULL; +- if (!g_file_set_contents (path, +- data, +- length, +- &error)) ++ if (!g_key_file_save_to_file (key_file, path, &error)) + { + g_prefix_error (&error, "Error writing key-value-file %s: ", path); + g_dbus_method_invocation_take_error (invocation, error); +@@ -1084,7 +1052,6 @@ on_account_handle_remove (GoaAccount *account, + + out: + g_clear_object (&provider); +- g_free (data); + g_clear_pointer (&key_file, (GDestroyNotify) g_key_file_free); + g_free (group); + g_free (path); +diff --git a/src/goabackend/goautils.c b/src/goabackend/goautils.c +index deb8236d9e35..6dbd53a06469 100644 +--- a/src/goabackend/goautils.c ++++ b/src/goabackend/goautils.c +@@ -380,12 +380,8 @@ goa_utils_keyfile_remove_key (GoaAccount *account, const gchar *key) + { + GError *error; + GKeyFile *key_file; +- gchar *contents; + gchar *group; + gchar *path; +- gsize length; +- +- contents = NULL; + + path = g_strdup_printf ("%s/goa-1.0/accounts.conf", g_get_user_config_dir ()); + group = g_strdup_printf ("Account %s", goa_account_get_id (account)); +@@ -407,10 +403,9 @@ goa_utils_keyfile_remove_key (GoaAccount *account, const gchar *key) + } + + g_key_file_remove_key (key_file, group, key, NULL); +- contents = g_key_file_to_data (key_file, &length, NULL); + + error = NULL; +- if (!g_file_set_contents (path, contents, length, &error)) ++ if (!g_key_file_save_to_file (key_file, path, &error)) + { + g_prefix_error (&error, "Error writing key-value-file %s: ", path); + g_warning ("%s (%s, %d)", error->message, g_quark_to_string (error->domain), error->code); +@@ -419,7 +414,6 @@ goa_utils_keyfile_remove_key (GoaAccount *account, const gchar *key) + } + + out: +- g_free (contents); + g_key_file_free (key_file); + g_free (group); + g_free (path); +@@ -430,12 +424,8 @@ goa_utils_keyfile_set_boolean (GoaAccount *account, const gchar *key, gboolean v + { + GError *error; + GKeyFile *key_file; +- gchar *contents; + gchar *group; + gchar *path; +- gsize length; +- +- contents = NULL; + + path = g_strdup_printf ("%s/goa-1.0/accounts.conf", g_get_user_config_dir ()); + group = g_strdup_printf ("Account %s", goa_account_get_id (account)); +@@ -457,10 +447,9 @@ goa_utils_keyfile_set_boolean (GoaAccount *account, const gchar *key, gboolean v + } + + g_key_file_set_boolean (key_file, group, key, value); +- contents = g_key_file_to_data (key_file, &length, NULL); + + error = NULL; +- if (!g_file_set_contents (path, contents, length, &error)) ++ if (!g_key_file_save_to_file (key_file, path, &error)) + { + g_prefix_error (&error, "Error writing key-value-file %s: ", path); + g_warning ("%s (%s, %d)", error->message, g_quark_to_string (error->domain), error->code); +@@ -469,7 +458,6 @@ goa_utils_keyfile_set_boolean (GoaAccount *account, const gchar *key, gboolean v + } + + out: +- g_free (contents); + g_key_file_free (key_file); + g_free (group); + g_free (path); +@@ -480,12 +468,8 @@ goa_utils_keyfile_set_string (GoaAccount *account, const gchar *key, const gchar + { + GError *error; + GKeyFile *key_file; +- gchar *contents; + gchar *group; + gchar *path; +- gsize length; +- +- contents = NULL; + + path = g_strdup_printf ("%s/goa-1.0/accounts.conf", g_get_user_config_dir ()); + group = g_strdup_printf ("Account %s", goa_account_get_id (account)); +@@ -507,10 +491,9 @@ goa_utils_keyfile_set_string (GoaAccount *account, const gchar *key, const gchar + } + + g_key_file_set_string (key_file, group, key, value); +- contents = g_key_file_to_data (key_file, &length, NULL); + + error = NULL; +- if (!g_file_set_contents (path, contents, length, &error)) ++ if (!g_key_file_save_to_file (key_file, path, &error)) + { + g_prefix_error (&error, "Error writing key-value-file %s: ", path); + g_warning ("%s (%s, %d)", error->message, g_quark_to_string (error->domain), error->code); +@@ -519,7 +502,6 @@ goa_utils_keyfile_set_string (GoaAccount *account, const gchar *key, const gchar + } + + out: +- g_free (contents); + g_key_file_free (key_file); + g_free (group); + g_free (path); +-- +2.5.5 + + +From ca9a49620b98455bdbef5b813cbf607bfec1759b Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Wed, 4 May 2016 18:47:43 +0200 +Subject: [PATCH 03/11] media-server: Don't touch the keyring + +Media servers (eg., DLNA) don't need any credentials, therefore don't +bother storing and looking up an empty entry in the keyring. + +https://bugzilla.gnome.org/show_bug.cgi?id=688041 +--- + src/goabackend/goamediaserverprovider.c | 44 ++------------------------------- + 1 file changed, 2 insertions(+), 42 deletions(-) + +diff --git a/src/goabackend/goamediaserverprovider.c b/src/goabackend/goamediaserverprovider.c +index 860fe1588043..c3b90b46b498 100644 +--- a/src/goabackend/goamediaserverprovider.c ++++ b/src/goabackend/goamediaserverprovider.c +@@ -189,35 +189,10 @@ ensure_credentials_sync (GoaProvider *provider, + GCancellable *cancellable, + GError **error) + { +- GVariant *credentials; +- gboolean ret; +- +- credentials = NULL; +- ret = FALSE; +- +- credentials = goa_utils_lookup_credentials_sync (provider, +- object, +- cancellable, +- error); +- +- if (credentials == NULL) +- { +- if (error != NULL) +- { +- (*error)->domain = GOA_ERROR; +- (*error)->code = GOA_ERROR_NOT_AUTHORIZED; +- goto out; +- } +- } +- + if (out_expires_in != NULL) + *out_expires_in = 0; + +- ret = TRUE; +- +- out: +- g_clear_pointer (&credentials, (GDestroyNotify) g_variant_unref); +- return ret; ++ return TRUE; + } + + /* ---------------------------------------------------------------------------------------------------- */ +@@ -542,28 +517,13 @@ refresh_account (GoaProvider *provider, + GError **error) + { + GoaAccount *account; +- GVariantBuilder credentials; +- gboolean ret; +- +- ret = FALSE; +- +- g_variant_builder_init (&credentials, G_VARIANT_TYPE_VARDICT); +- +- if (!goa_utils_store_credentials_for_object_sync (provider, +- object, +- g_variant_builder_end (&credentials), +- NULL, /* GCancellable */ +- error)) +- goto out; + + account = goa_object_peek_account (object); + goa_account_call_ensure_credentials (account, + NULL, /* GCancellable */ + NULL, NULL); /* callback, user_data */ +- ret = TRUE; + +- out: +- return ret; ++ return TRUE; + } + + /* ---------------------------------------------------------------------------------------------------- */ +-- +2.5.5 + + +From ae365bdc72ad0d95d6c9db019e6608e9cae46ba0 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Fri, 6 May 2016 18:50:41 +0200 +Subject: [PATCH 04/11] daemon: Move object_path_to_group to its own area + +In a subsequent commit, we are going to add one more similar utility +function that will be used in multiple places. Therefore, let's club +them together and give them a separate home. + +https://bugzilla.gnome.org/show_bug.cgi?id=688041 +--- + src/daemon/goadaemon.c | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +diff --git a/src/daemon/goadaemon.c b/src/daemon/goadaemon.c +index 67f43151ea7c..d799a09db669 100644 +--- a/src/daemon/goadaemon.c ++++ b/src/daemon/goadaemon.c +@@ -350,6 +350,15 @@ diff_sorted_lists (GList *list1, + + /* ---------------------------------------------------------------------------------------------------- */ + ++static gchar * ++object_path_to_group (const gchar *object_path) ++{ ++ g_return_val_if_fail (g_str_has_prefix (object_path, "/org/gnome/OnlineAccounts/Accounts/"), NULL); ++ return g_strdup_printf ("Account %s", object_path + sizeof "/org/gnome/OnlineAccounts/Accounts/" - 1); ++} ++ ++/* ---------------------------------------------------------------------------------------------------- */ ++ + typedef struct + { + GKeyFile *key_file; +@@ -558,13 +567,6 @@ update_account_object (GoaDaemon *self, + return ret; + } + +-static gchar * +-object_path_to_group (const gchar *object_path) +-{ +- g_return_val_if_fail (g_str_has_prefix (object_path, "/org/gnome/OnlineAccounts/Accounts/"), NULL); +- return g_strdup_printf ("Account %s", object_path + sizeof "/org/gnome/OnlineAccounts/Accounts/" - 1); +-} +- + static void + process_config_entries (GoaDaemon *self, + GHashTable *group_name_to_key_file_data) +-- +2.5.5 + + +From 345e5c4e62632560bc767aad3d3904ad8379ef1f Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Fri, 6 May 2016 18:53:11 +0200 +Subject: [PATCH 05/11] daemon: Rename the variable 'id' to 'group' + +It refers to the name of a group in the key file, not an ID. + +https://bugzilla.gnome.org/show_bug.cgi?id=688041 +--- + src/daemon/goadaemon.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/src/daemon/goadaemon.c b/src/daemon/goadaemon.c +index d799a09db669..450bda7406e6 100644 +--- a/src/daemon/goadaemon.c ++++ b/src/daemon/goadaemon.c +@@ -572,7 +572,7 @@ process_config_entries (GoaDaemon *self, + GHashTable *group_name_to_key_file_data) + { + GHashTableIter iter; +- const gchar *id; ++ const gchar *group; + KeyFileData *key_file_data; + GList *existing_object_paths; + GList *config_object_paths; +@@ -598,15 +598,15 @@ process_config_entries (GoaDaemon *self, + + config_object_paths = NULL; + g_hash_table_iter_init (&iter, group_name_to_key_file_data); +- while (g_hash_table_iter_next (&iter, (gpointer*) &id, (gpointer*) &key_file_data)) ++ while (g_hash_table_iter_next (&iter, (gpointer*) &group, (gpointer*) &key_file_data)) + { + gchar *object_path; + + /* create and validate object path */ +- object_path = g_strdup_printf ("/org/gnome/OnlineAccounts/Accounts/%s", id + sizeof "Account " - 1); +- if (strstr (id + sizeof "Account " - 1, "/") != NULL || !g_variant_is_object_path (object_path)) ++ object_path = g_strdup_printf ("/org/gnome/OnlineAccounts/Accounts/%s", group + sizeof "Account " - 1); ++ if (strstr (group + sizeof "Account " - 1, "/") != NULL || !g_variant_is_object_path (object_path)) + { +- g_warning ("`%s' is not a valid account identifier", id); ++ g_warning ("`%s' is not a valid account identifier", group); + g_free (object_path); + continue; + } +-- +2.5.5 + + +From 63d0c7f7e64ef7d68df30a7f63c397651df346e9 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Fri, 6 May 2016 19:00:32 +0200 +Subject: [PATCH 06/11] daemon: Refactor code to get ID from group name into a + function + +https://bugzilla.gnome.org/show_bug.cgi?id=688041 +--- + src/daemon/goadaemon.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/src/daemon/goadaemon.c b/src/daemon/goadaemon.c +index 450bda7406e6..6335c6708718 100644 +--- a/src/daemon/goadaemon.c ++++ b/src/daemon/goadaemon.c +@@ -350,6 +350,13 @@ diff_sorted_lists (GList *list1, + + /* ---------------------------------------------------------------------------------------------------- */ + ++static const gchar * ++group_to_id (const gchar *group) ++{ ++ g_return_val_if_fail (g_str_has_prefix (group, "Account "), NULL); ++ return group + sizeof "Account " - 1; ++} ++ + static gchar * + object_path_to_group (const gchar *object_path) + { +@@ -600,11 +607,14 @@ process_config_entries (GoaDaemon *self, + g_hash_table_iter_init (&iter, group_name_to_key_file_data); + while (g_hash_table_iter_next (&iter, (gpointer*) &group, (gpointer*) &key_file_data)) + { ++ const gchar *id; + gchar *object_path; + ++ id = group_to_id (group); ++ + /* create and validate object path */ +- object_path = g_strdup_printf ("/org/gnome/OnlineAccounts/Accounts/%s", group + sizeof "Account " - 1); +- if (strstr (group + sizeof "Account " - 1, "/") != NULL || !g_variant_is_object_path (object_path)) ++ object_path = g_strdup_printf ("/org/gnome/OnlineAccounts/Accounts/%s", id); ++ if (strstr (id, "/") != NULL || !g_variant_is_object_path (object_path)) + { + g_warning ("`%s' is not a valid account identifier", group); + g_free (object_path); +-- +2.5.5 + + +From e7a111758703a55c10193db962b7fea0467c10d1 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Fri, 6 May 2016 19:04:35 +0200 +Subject: [PATCH 07/11] daemon, utils: Rename goa_utils_delete_credentials_sync + +... because we are going to add a for_id variant in a subsequent +commit. + +https://bugzilla.gnome.org/show_bug.cgi?id=688041 +--- + src/daemon/goadaemon.c | 2 +- + src/goabackend/goautils.c | 8 ++++---- + src/goabackend/goautils.h | 8 ++++---- + 3 files changed, 9 insertions(+), 9 deletions(-) + +diff --git a/src/daemon/goadaemon.c b/src/daemon/goadaemon.c +index 6335c6708718..1d04e02fe3a2 100644 +--- a/src/daemon/goadaemon.c ++++ b/src/daemon/goadaemon.c +@@ -1052,7 +1052,7 @@ on_account_handle_remove (GoaAccount *account, + } + + error = NULL; +- if (!goa_utils_delete_credentials_sync (provider, account, NULL, &error)) ++ if (!goa_utils_delete_credentials_for_account_sync (provider, account, NULL, &error)) + { + g_dbus_method_invocation_take_error (invocation, error); + goto out; +diff --git a/src/goabackend/goautils.c b/src/goabackend/goautils.c +index 6dbd53a06469..c58ccb82c5d3 100644 +--- a/src/goabackend/goautils.c ++++ b/src/goabackend/goautils.c +@@ -169,10 +169,10 @@ goa_utils_set_dialog_title (GoaProvider *provider, GtkDialog *dialog, gboolean a + } + + gboolean +-goa_utils_delete_credentials_sync (GoaProvider *provider, +- GoaAccount *object, +- GCancellable *cancellable, +- GError **error) ++goa_utils_delete_credentials_for_account_sync (GoaProvider *provider, ++ GoaAccount *object, ++ GCancellable *cancellable, ++ GError **error) + { + gboolean ret; + gchar *password_key; +diff --git a/src/goabackend/goautils.h b/src/goabackend/goautils.h +index ca3671bcbc9a..baf475548d8c 100644 +--- a/src/goabackend/goautils.h ++++ b/src/goabackend/goautils.h +@@ -54,10 +54,10 @@ gchar *goa_utils_data_input_stream_read_line (GDataInputStream *strea + + void goa_utils_set_dialog_title (GoaProvider *provider, GtkDialog *dialog, gboolean add_account); + +-gboolean goa_utils_delete_credentials_sync (GoaProvider *provider, +- GoaAccount *account, +- GCancellable *cancellable, +- GError **error); ++gboolean goa_utils_delete_credentials_for_account_sync (GoaProvider *provider, ++ GoaAccount *account, ++ GCancellable *cancellable, ++ GError **error); + + GVariant *goa_utils_lookup_credentials_sync (GoaProvider *provider, + GoaObject *object, +-- +2.5.5 + + +From 9bbf94ba603903565d09e3c2a832d349d412d05b Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Fri, 6 May 2016 19:11:02 +0200 +Subject: [PATCH 08/11] utils: Add goa_utils_delete_credentials_for_id_sync + helper + +https://bugzilla.gnome.org/show_bug.cgi?id=688041 +--- + src/goabackend/goautils.c | 22 ++++++++++++++++++---- + src/goabackend/goautils.h | 5 +++++ + 2 files changed, 23 insertions(+), 4 deletions(-) + +diff --git a/src/goabackend/goautils.c b/src/goabackend/goautils.c +index c58ccb82c5d3..553adf36df21 100644 +--- a/src/goabackend/goautils.c ++++ b/src/goabackend/goautils.c +@@ -174,13 +174,29 @@ goa_utils_delete_credentials_for_account_sync (GoaProvider *provider, + GCancellable *cancellable, + GError **error) + { ++ const gchar *id; ++ ++ g_return_val_if_fail (GOA_IS_PROVIDER (provider), FALSE); ++ g_return_val_if_fail (GOA_IS_ACCOUNT (object), FALSE); ++ g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); ++ g_return_val_if_fail (error == NULL || *error == NULL, FALSE); ++ ++ id = goa_account_get_id (object); ++ return goa_utils_delete_credentials_for_id_sync (provider, id, cancellable, error); ++} ++ ++gboolean ++goa_utils_delete_credentials_for_id_sync (GoaProvider *provider, ++ const gchar *id, ++ GCancellable *cancellable, ++ GError **error) ++{ + gboolean ret; + gchar *password_key; +- const gchar *id; + GError *sec_error = NULL; + + g_return_val_if_fail (GOA_IS_PROVIDER (provider), FALSE); +- g_return_val_if_fail (GOA_IS_ACCOUNT (object), FALSE); ++ g_return_val_if_fail (id != NULL && id[0] != '\0', FALSE); + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + +@@ -188,8 +204,6 @@ goa_utils_delete_credentials_for_account_sync (GoaProvider *provider, + + password_key = NULL; + +- id = goa_account_get_id (object); +- + password_key = g_strdup_printf ("%s:gen%d:%s", + goa_provider_get_provider_type (GOA_PROVIDER (provider)), + goa_provider_get_credentials_generation (GOA_PROVIDER (provider)), +diff --git a/src/goabackend/goautils.h b/src/goabackend/goautils.h +index baf475548d8c..07a3c70353f9 100644 +--- a/src/goabackend/goautils.h ++++ b/src/goabackend/goautils.h +@@ -59,6 +59,11 @@ gboolean goa_utils_delete_credentials_for_account_sync (GoaProvider * + GCancellable *cancellable, + GError **error); + ++gboolean goa_utils_delete_credentials_for_id_sync (GoaProvider *provider, ++ const gchar *id, ++ GCancellable *cancellable, ++ GError **error); ++ + GVariant *goa_utils_lookup_credentials_sync (GoaProvider *provider, + GoaObject *object, + GCancellable *cancellable, +-- +2.5.5 + + +From f022f0d737ee9d9ad6fd345fc458c3d49667f44e Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Thu, 5 May 2016 17:37:17 +0200 +Subject: [PATCH 09/11] daemon: Clean up temporary accounts (eg., Kerberos) + +... by removing them from both accounts.conf and the keyring. + +https://bugzilla.gnome.org/show_bug.cgi?id=688041 +--- + src/daemon/goadaemon.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 48 insertions(+), 1 deletion(-) + +diff --git a/src/daemon/goadaemon.c b/src/daemon/goadaemon.c +index 1d04e02fe3a2..3f3fd47e9b62 100644 +--- a/src/daemon/goadaemon.c ++++ b/src/daemon/goadaemon.c +@@ -421,6 +421,7 @@ add_config_file (GoaDaemon *self, + } + else + { ++ gboolean needs_update = FALSE; + gchar **groups; + const char *guid; + gsize num_groups; +@@ -451,9 +452,44 @@ add_config_file (GoaDaemon *self, + if (session_id != NULL && + g_strcmp0 (session_id, guid) != 0) + { ++ GoaProvider *provider = NULL; ++ const gchar *id; ++ gchar *provider_type = NULL; ++ + g_debug ("ignoring account \"%s\" in file %s because it's stale", + groups[n], path); ++ ++ needs_update = g_key_file_remove_group (key_file, groups[n], NULL); ++ ++ id = group_to_id (groups[n]); ++ if (id == NULL) ++ { ++ g_warning ("Unable to get account ID from group: %s", groups[n]); ++ goto cleanup_and_continue; ++ } ++ ++ provider_type = g_key_file_get_string (key_file, groups[n], "Provider", NULL); ++ if (provider_type != NULL) ++ provider = goa_provider_get_for_provider_type (provider_type); ++ ++ if (provider == NULL) ++ { ++ g_warning ("Unsupported account type %s for ID %s (no provider)", provider_type, id); ++ goto cleanup_and_continue; ++ } ++ ++ error = NULL; ++ if (!goa_utils_delete_credentials_for_id_sync (provider, id, NULL, &error)) ++ { ++ g_warning ("Unable to clean-up stale keyring entries: %s", error->message); ++ g_error_free (error); ++ goto cleanup_and_continue; ++ } ++ ++ cleanup_and_continue: ++ g_clear_object (&provider); + g_free (groups[n]); ++ g_free (provider_type); + g_free (session_id); + continue; + } +@@ -461,7 +497,7 @@ add_config_file (GoaDaemon *self, + } + else + { +- g_key_file_remove_key (key_file, groups[n], "SessionId", NULL); ++ needs_update = g_key_file_remove_key (key_file, groups[n], "SessionId", NULL); + } + + g_hash_table_insert (group_name_to_key_file_data, +@@ -476,6 +512,17 @@ add_config_file (GoaDaemon *self, + } + g_free (groups); + ++ if (needs_update) ++ { ++ error = NULL; ++ if (!g_key_file_save_to_file (key_file, path, &error)) ++ { ++ g_prefix_error (&error, "Error writing key-value-file %s: ", path); ++ g_warning ("%s (%s, %d)", error->message, g_quark_to_string (error->domain), error->code); ++ g_error_free (error); ++ } ++ } ++ + *key_files_to_free = g_list_prepend (*key_files_to_free, key_file); + } + } +-- +2.5.5 + + +From 306d78cf1014797967c20c3959d4c8b122cb5574 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Thu, 5 May 2016 17:43:35 +0200 +Subject: [PATCH 10/11] daemon: Don't store empty entries in the keyring + +If the account is being created without any credentials, then we assume +that the backend either (a) doesn't need any credentials (eg., media +servers), or (b) has other means of differentiating between accounts +that need credentials and those that do not (eg., Kerberos). + +https://bugzilla.gnome.org/show_bug.cgi?id=688041 +--- + src/daemon/goadaemon.c | 21 +++++++++++++-------- + 1 file changed, 13 insertions(+), 8 deletions(-) + +diff --git a/src/daemon/goadaemon.c b/src/daemon/goadaemon.c +index 3f3fd47e9b62..213f154c12aa 100644 +--- a/src/daemon/goadaemon.c ++++ b/src/daemon/goadaemon.c +@@ -844,6 +844,7 @@ get_all_providers_cb (GObject *source, + gchar *group; + gchar *key_file_data; + gsize length; ++ gsize n_credentials; + gchar *object_path; + GVariantIter iter; + const gchar *key; +@@ -957,14 +958,18 @@ get_all_providers_cb (GObject *source, + goto out; + } + +- /* We don't want to fail AddAccount if we could not store the +- * credentials in the keyring. +- */ +- goa_utils_store_credentials_for_id_sync (provider, +- id, +- data->credentials, +- NULL, /* GCancellable */ +- NULL); ++ n_credentials = g_variant_n_children (data->credentials); ++ if (n_credentials > 0) ++ { ++ /* We don't want to fail AddAccount if we could not store the ++ * credentials in the keyring. ++ */ ++ goa_utils_store_credentials_for_id_sync (provider, ++ id, ++ data->credentials, ++ NULL, /* GCancellable */ ++ NULL); ++ } + + goa_daemon_reload_configuration (data->daemon); + +-- +2.5.5 + + +From 2c93ab96ad922d380f0c2e4808e21d2864e97129 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Mon, 18 Jul 2016 15:01:06 +0200 +Subject: [PATCH 11/11] daemon: Ensure temporary accounts are really removed + from the keyring + +We should remove the GKeyFile group only after we have read everything +that we need from it. Otherwise, it will lead to: + goa-daemon-WARNING **: Unsupported account type (null) for ID + account_1466692958_0 (no provider) + +Fall out from 56c056df2b5e3bc7f44dbc0915fa431db7628d91 + +https://bugzilla.gnome.org/show_bug.cgi?id=688041 +--- + src/daemon/goadaemon.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/daemon/goadaemon.c b/src/daemon/goadaemon.c +index 213f154c12aa..04cb2403432a 100644 +--- a/src/daemon/goadaemon.c ++++ b/src/daemon/goadaemon.c +@@ -459,8 +459,6 @@ add_config_file (GoaDaemon *self, + g_debug ("ignoring account \"%s\" in file %s because it's stale", + groups[n], path); + +- needs_update = g_key_file_remove_group (key_file, groups[n], NULL); +- + id = group_to_id (groups[n]); + if (id == NULL) + { +@@ -478,6 +476,8 @@ add_config_file (GoaDaemon *self, + goto cleanup_and_continue; + } + ++ needs_update = g_key_file_remove_group (key_file, groups[n], NULL); ++ + error = NULL; + if (!goa_utils_delete_credentials_for_id_sync (provider, id, NULL, &error)) + { +-- +2.5.5 + diff --git a/SPECS/gnome-online-accounts.spec b/SPECS/gnome-online-accounts.spec index 9947d60..8410de4 100644 --- a/SPECS/gnome-online-accounts.spec +++ b/SPECS/gnome-online-accounts.spec @@ -1,6 +1,6 @@ Name: gnome-online-accounts -Version: 3.14.4 -Release: 3%{?dist} +Version: 3.14.5 +Release: 5%{?dist} Summary: Single sign-on framework for GNOME Group: System Environment/Libraries @@ -9,17 +9,26 @@ URL: https://live.gnome.org/GnomeOnlineAccounts Source0: http://download.gnome.org/sources/gnome-online-accounts/3.14/%{name}-%{version}.tar.xz Patch0: translations.patch -Patch1: 0001-daemon-Don-t-leak-the-GoaProvider.patch -Patch2: kerberos-smartcard.patch -Patch3: kerberos-separate-process.patch -Patch4: ensure-credentials-startup-and-network-change.patch -Patch5: kerberos-fix-renewal.patch +Patch1: kerberos-smartcard.patch +Patch2: kerberos-separate-process.patch +Patch3: ensure-credentials-startup-and-network-change.patch +Patch4: kerberos-fix-renewal.patch + +# https://bugzilla.redhat.com/show_bug.cgi?id=1261940 +Patch5: temporary-accounts-clean-up.patch + +# https://bugzilla.redhat.com/show_bug.cgi?id=1267534 +Patch6: telepathy-account-widgets-update-submodule.patch +Patch7: kerberos-telepathy-stopping-goa-daemon-removes-account.patch + +# https://bugzilla.redhat.com/show_bug.cgi?id=1364705 +Patch8: kerberos-fail-early-on-ticket-request-when-ticketing.patch BuildRequires: autoconf BuildRequires: automake BuildRequires: gcr-devel -BuildRequires: glib2-devel >= 2.35 -BuildRequires: gtk3-devel >= 3.5.1 +BuildRequires: glib2-devel >= 2.40 +BuildRequires: gtk3-devel >= 3.11.1 BuildRequires: gnome-common BuildRequires: gobject-introspection-devel BuildRequires: gtk-doc @@ -56,11 +65,14 @@ developing applications that use %{name}. %prep %setup -q %patch0 -p1 -b .translations -%patch1 -p1 -b .provider-leak -%patch2 -p1 -b .kerberos-smartcard -%patch3 -p1 -b .kerberos-separate-process -%patch4 -p1 -b .ensure-credentials -%patch5 -p1 -b .kerberos-fix-renewal +%patch1 -p1 -b .kerberos-smartcard +%patch2 -p1 -b .kerberos-separate-process +%patch3 -p1 -b .ensure-credentials +%patch4 -p1 -b .kerberos-fix-renewal +%patch5 -p1 -b .temporary-accounts-clean-up +%patch6 -p1 -b .tpaw-update +%patch7 -p1 -b .stopping-goa-daemon-removes +%patch8 -p1 -b .fail-early-on-ticket-request %build autoreconf --force --install @@ -136,6 +148,29 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || : %{_libdir}/goa-1.0/include %changelog +* Tue Aug 23 2016 Debarshi Ray - 3.14.5-5 +- Ensure that temporary accounts are really removed from the keyring and + avoid a WARNING +Resolves: #1261940 + +* Wed Aug 10 2016 Debarshi Ray - 3.14.5-4 +- Fail early on Kerberos ticket request when ticketing is disabled +Resolves: #1364705 + +* Mon Jun 13 2016 Debarshi Ray - 3.14.5-3 +- Don't remove Telepathy accounts or expire Kerberos credentials when stopping + goa-daemon +Resolves: #1267534 + +* Wed May 18 2016 Debarshi Ray - 3.14.5-2 +- Don't let temporary accounts accumulate in accounts.conf and the keyring +Resolves: #1261940 + +* Mon Mar 14 2016 Debarshi Ray - 3.14.5-1 +- Update to 3.14.5 +- Rebase downstream patches +Resolves: #1310832 + * Tue Sep 22 2015 Ray Strode 3.14.4-3 - Fix kerberos renewal for KDCs that support it Resolves: #1189888