/* * This code is from evolution with this license: * * This program 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) version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with the program; if not, see * */ #include "config.h" #include #include #include #define GOA_API_IS_SUBJECT_TO_CHANGE #include #include static void eds_show_source_error (const gchar *where, const gchar *what, ESource *source, const GError *error) { if (!error || g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) return; /* TODO Show the error in UI, somehow */ g_warning ("%s: %s '%s': %s", where, what, e_source_get_display_name (source), error->message); } static void eds_source_invoke_authenticate_cb (GObject *source_object, GAsyncResult *result, gpointer user_data) { ESource *source = E_SOURCE (source_object); GError *error = NULL; if (!e_source_invoke_authenticate_finish (source, result, &error) && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { eds_show_source_error (G_STRFUNC, "Failed to invoke authenticate", source, error); } g_clear_error (&error); } static void eds_source_trust_prompt_done_cb (GObject *source_object, GAsyncResult *result, gpointer user_data) { ETrustPromptResponse response = E_TRUST_PROMPT_RESPONSE_UNKNOWN; ESource *source = E_SOURCE (source_object); GError *error = NULL; if (!e_trust_prompt_run_for_source_finish (source, result, &response, &error)) { eds_show_source_error (G_STRFUNC, "Failed to prompt for trust for", source, error); } else if (response == E_TRUST_PROMPT_RESPONSE_ACCEPT || response == E_TRUST_PROMPT_RESPONSE_ACCEPT_TEMPORARILY) { /* Use NULL credentials to reuse those from the last time. */ e_source_invoke_authenticate (source, NULL, NULL /* cancellable */, eds_source_invoke_authenticate_cb, NULL); } g_clear_error (&error); } static void eds_source_credentials_required_cb (ESourceRegistry *registry, ESource *source, ESourceCredentialsReason reason, const gchar *certificate_pem, GTlsCertificateFlags certificate_errors, const GError *op_error, ECredentialsPrompter *credentials_prompter) { if (e_credentials_prompter_get_auto_prompt_disabled_for (credentials_prompter, source)) return; if (reason == E_SOURCE_CREDENTIALS_REASON_SSL_FAILED) { e_trust_prompt_run_for_source (e_credentials_prompter_get_dialog_parent (credentials_prompter), source, certificate_pem, certificate_errors, op_error ? op_error->message : NULL, TRUE /* allow_source_save */, NULL /* cancellable */, eds_source_trust_prompt_done_cb, NULL); } else if (reason == E_SOURCE_CREDENTIALS_REASON_ERROR && op_error) { eds_show_source_error (G_STRFUNC, "Failed to authenticate", source, op_error); } } ESourceRegistry *eds_source_registry = NULL; static ECredentialsPrompter *eds_credentials_prompter = NULL; gboolean contacts_ensure_eds_accounts (void) { ESourceCredentialsProvider *credentials_provider; GList *list, *link; GError *error = NULL; if (eds_source_registry) return TRUE; /* XXX This blocks while connecting to the D-Bus service. * Maybe it should be created in the Contacts class * and passed in as needed? */ eds_source_registry = e_source_registry_new_sync (NULL, &error); /* If this fails it's game over. */ if (error != NULL) { g_error ("%s: %s", G_STRFUNC, error->message); return FALSE; } eds_credentials_prompter = e_credentials_prompter_new (eds_source_registry); /* First disable credentials prompt for all but addressbook sources... */ list = e_source_registry_list_sources (eds_source_registry, NULL); for (link = list; link != NULL; link = g_list_next (link)) { ESource *source = E_SOURCE (link->data); /* Mark for skip also currently disabled sources */ if (!e_source_has_extension (source, E_SOURCE_EXTENSION_ADDRESS_BOOK)) e_credentials_prompter_set_auto_prompt_disabled_for (eds_credentials_prompter, source, TRUE); } g_list_free_full (list, g_object_unref); credentials_provider = e_credentials_prompter_get_provider (eds_credentials_prompter); /* ...then enable credentials prompt for credential source of the addressbook sources, which can be a collection source. */ list = e_source_registry_list_sources (eds_source_registry, E_SOURCE_EXTENSION_ADDRESS_BOOK); for (link = list; link != NULL; link = g_list_next (link)) { ESource *source = E_SOURCE (link->data), *cred_source; cred_source = e_source_credentials_provider_ref_credentials_source (credentials_provider, source); if (cred_source && !e_source_equal (source, cred_source)) e_credentials_prompter_set_auto_prompt_disabled_for (eds_credentials_prompter, cred_source, FALSE); g_clear_object (&cred_source); } g_list_free_full (list, g_object_unref); /* The eds_credentials_prompter responses to REQUIRED and REJECTED reasons, the SSL_FAILED should be handled elsewhere. */ g_signal_connect (eds_source_registry, "credentials-required", G_CALLBACK (eds_source_credentials_required_cb), eds_credentials_prompter); e_credentials_prompter_process_awaiting_credentials (eds_credentials_prompter); return TRUE; } gboolean contacts_has_goa_account (void) { GList *list, *link; gboolean has_goa_contacts = FALSE; list = e_source_registry_list_sources (eds_source_registry, E_SOURCE_EXTENSION_GOA); for (link = list; link != NULL; link = g_list_next (link)) { ESource *source = E_SOURCE (link->data); ESourceCollection *extension; /* Ignore disabled accounts. */ if (!e_source_get_enabled (source)) continue; /* All ESources with a [GNOME Online Accounts] extension * should also have a [Collection] extension. Verify it. */ if (!e_source_has_extension (source, E_SOURCE_EXTENSION_COLLECTION)) continue; extension = e_source_get_extension (source, E_SOURCE_EXTENSION_COLLECTION); /* This corresponds to the Contacts ON/OFF switch in GOA. */ if (e_source_collection_get_contacts_enabled (extension)) { has_goa_contacts = TRUE; break; } } g_list_free_full (list, (GDestroyNotify) g_object_unref); return has_goa_contacts; } gboolean contacts_esource_uid_is_google (const char *uid) { ESource *source; gboolean uid_is_google = FALSE; source = e_source_registry_ref_source (eds_source_registry, uid); if (source == NULL) return FALSE; /* Make sure it's really an address book. */ if (e_source_has_extension (source, E_SOURCE_EXTENSION_ADDRESS_BOOK)) { ESourceBackend *extension; const gchar *backend_name; extension = e_source_get_extension (source, E_SOURCE_EXTENSION_ADDRESS_BOOK); backend_name = e_source_backend_get_backend_name (extension); uid_is_google = (g_strcmp0 (backend_name, "google") == 0); } g_object_unref (source); return uid_is_google; } const char * contacts_lookup_esource_name_by_uid (const char *uid) { ESource *source; ESource *builtin_address_book; const gchar *display_name; source = e_source_registry_ref_source (eds_source_registry, uid); if (source == NULL) return NULL; builtin_address_book = e_source_registry_ref_builtin_address_book (eds_source_registry); if (e_source_equal (source, builtin_address_book)) display_name = _("Local Address Book"); else if (contacts_esource_uid_is_google (uid)) display_name = _("Google"); else display_name = e_source_get_display_name (source); g_object_unref (builtin_address_book); g_object_unref (source); return display_name; } const char * contacts_lookup_esource_name_by_uid_for_contact (const char *uid) { ESource *source; ESource *builtin_address_book; const gchar *display_name; source = e_source_registry_ref_source (eds_source_registry, uid); if (source == NULL) return NULL; builtin_address_book = e_source_registry_ref_builtin_address_book (eds_source_registry); if (e_source_equal (source, builtin_address_book)) return _("Local Contact"); else if (contacts_esource_uid_is_google (uid)) display_name = _("Google"); else display_name = e_source_get_display_name (source); g_object_unref (builtin_address_book); g_object_unref (source); return display_name; } GtkWidget* contacts_get_icon_for_goa_account (const char* goa_id) { GoaClient *client; GoaObject *goa_object; GoaAccount *goa_account; GError *error; const gchar* icon_data; GIcon *provider_icon; GtkWidget *image_icon; error = NULL; client = goa_client_new_sync (NULL, &error); if (client == NULL) { g_error_free (error); return NULL; } goa_object = goa_client_lookup_by_id (client, goa_id); goa_account = goa_object_get_account (goa_object); icon_data = goa_account_get_provider_icon (goa_account); error = NULL; provider_icon = g_icon_new_for_string (icon_data, &error); if (provider_icon == NULL) { g_debug ("Error obtaining provider_icon"); g_error_free (error); } image_icon = gtk_image_new_from_gicon (provider_icon, GTK_ICON_SIZE_DIALOG); g_object_unref (goa_account); g_object_unref (goa_object); g_clear_object (&client); return image_icon; }