gboolean goa_utils_delete_credentials_sync (GoaProvider *provider, GoaAccount *object, 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 (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); ret = FALSE; 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)), id); secret_password_clear_sync (&secret_password_schema, cancellable, &sec_error, "goa-identity", password_key, NULL); if (sec_error != NULL) { g_warning ("secret_password_clear_sync() failed: %s", sec_error->message); g_set_error_literal (error, GOA_ERROR, GOA_ERROR_FAILED, /* TODO: more specific */ _("Failed to delete credentials from the keyring")); g_error_free (sec_error); goto out; } g_debug ("Cleared keyring credentials for id: %s", id); ret = TRUE; out: g_free (password_key); return ret; }
static GoaProvider * get_provider (GoaProviderFactory *factory, const gchar *provider_name) { g_return_val_if_fail (GOA_IS_TELEPATHY_FACTORY (factory), NULL); return GOA_PROVIDER (goa_telepathy_provider_new_from_protocol_name (provider_name)); }
void goa_utils_set_dialog_title (GoaProvider *provider, GtkDialog *dialog, gboolean add_account) { gchar *provider_name; gchar *title; provider_name = goa_provider_get_provider_name (GOA_PROVIDER (provider), NULL); /* Translators: the %s is the name of the provider. eg., Google. */ title = g_strdup_printf (_("%s account"), provider_name); gtk_window_set_title (GTK_WINDOW (dialog), title); g_free (title); g_free (provider_name); }
int main (int argc, char **argv) { GetAllData data = {0,}; GoaProvider *provider; GList *l; data.loop = g_main_loop_new (NULL, FALSE); goa_provider_get_all (get_all_cb, &data); g_main_loop_run (data.loop); if (data.error != NULL) { g_printerr ("Failed to list providers: %s (%s, %d)\n", data.error->message, g_quark_to_string (data.error->domain), data.error->code); g_error_free (data.error); goto out; } for (l = data.providers; l != NULL; l = l->next) { char *provider_name; provider = GOA_PROVIDER (l->data); provider_name = goa_provider_get_provider_name (provider, NULL); g_print ("Got provider %s\n", provider_name); g_free (provider_name); provider = NULL; } out: g_main_loop_unref (data.loop); g_list_free_full (data.providers, g_object_unref); return 0; }
static void get_all_providers_cb (GObject *source, GAsyncResult *res, gpointer user_data) { AddAccountData *data = user_data; GoaProvider *provider; GKeyFile *key_file; GError *error; GList *providers; GList *l; gchar *path; gchar *id; gchar *group; gchar *key_file_data; gsize length; gchar *object_path; GVariantIter iter; const gchar *key; const gchar *value; /* TODO: could check for @type */ provider = NULL; key_file = NULL; providers = NULL; path = NULL; id = NULL; group = NULL; key_file_data = NULL; object_path = NULL; if (!goa_provider_get_all_finish (&providers, res, NULL)) goto out; for (l = providers; l != NULL; l = l->next) { GoaProvider *p; const gchar *type; p = GOA_PROVIDER (l->data); type = goa_provider_get_provider_type (p); if (g_strcmp0 (type, data->provider_type) == 0) { provider = p; break; } } if (provider == NULL) { error= NULL; g_set_error (&error, GOA_ERROR, GOA_ERROR_FAILED, /* TODO: more specific */ _("Failed to find a provider for: %s"), data->provider_type); g_dbus_method_invocation_return_gerror (data->invocation, error); goto out; } key_file = g_key_file_new (); path = g_strdup_printf ("%s/goa-1.0/accounts.conf", g_get_user_config_dir ()); error = NULL; if (!g_file_get_contents (path, &key_file_data, &length, &error)) { if (error->domain == G_FILE_ERROR && error->code == G_FILE_ERROR_NOENT) { g_error_free (error); } else { g_prefix_error (&error, "Error loading file %s: ", path); g_dbus_method_invocation_return_gerror (data->invocation, error); goto out; } } else { if (length > 0) { error = NULL; if (!g_key_file_load_from_data (key_file, key_file_data, length, G_KEY_FILE_KEEP_COMMENTS, &error)) { g_prefix_error (&error, "Error parsing key-value-file %s: ", path); g_dbus_method_invocation_return_gerror (data->invocation, error); goto out; } } } id = generate_new_id (data->daemon); group = g_strdup_printf ("Account %s", id); g_key_file_set_string (key_file, group, "Provider", data->provider_type); g_key_file_set_string (key_file, group, "Identity", data->identity); g_key_file_set_string (key_file, group, "PresentationIdentity", data->presentation_identity); g_variant_iter_init (&iter, data->details); while (g_variant_iter_next (&iter, "{&s&s}", &key, &value)) { /* We treat IsTemporary special. If it's true we add in * the current session guid, so it can be ignored after * the session is over. */ if (g_strcmp0 (key, "IsTemporary") == 0) { if (g_strcmp0 (value, "true") == 0) { const char *guid; guid = g_dbus_connection_get_guid (data->daemon->connection); g_key_file_set_string (key_file, group, "SessionId", guid); } } 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_return_gerror (data->invocation, error); goto out; } error = NULL; if (!g_file_set_contents (path, key_file_data, length, &error)) { g_prefix_error (&error, "Error writing key-value-file %s: ", path); g_dbus_method_invocation_return_gerror (data->invocation, error); 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); goa_daemon_reload_configuration (data->daemon); object_path = g_strdup_printf ("/org/gnome/OnlineAccounts/Accounts/%s", id); goa_manager_complete_add_account (data->manager, data->invocation, object_path); out: g_free (object_path); if (providers != NULL) g_list_free_full (providers, g_object_unref); g_free (key_file_data); g_free (group); g_free (id); g_free (path); if (key_file != NULL) g_key_file_free (key_file); g_object_unref (data->daemon); g_object_unref (data->manager); g_object_unref (data->invocation); g_free (data->provider_type); g_free (data->identity); g_free (data->presentation_identity); g_variant_unref (data->credentials); g_variant_unref (data->details); g_slice_free (AddAccountData, data); }
gboolean goa_utils_store_credentials_for_id_sync (GoaProvider *provider, const gchar *id, GVariant *credentials, GCancellable *cancellable, GError **error) { gboolean ret; gchar *credentials_str; gchar *password_description; gchar *password_key; GError *sec_error = NULL; g_return_val_if_fail (GOA_IS_PROVIDER (provider), FALSE); g_return_val_if_fail (id != NULL && id[0] != '\0', FALSE); g_return_val_if_fail (credentials != NULL, FALSE); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); ret = FALSE; credentials_str = g_variant_print (credentials, TRUE); g_variant_ref_sink (credentials); g_variant_unref (credentials); 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)), id); /* Translators: The %s is the type of the provider, e.g. 'google' or 'yahoo' */ password_description = g_strdup_printf (_("GOA %s credentials for identity %s"), goa_provider_get_provider_type (GOA_PROVIDER (provider)), id); if (!secret_password_store_sync (&secret_password_schema, SECRET_COLLECTION_DEFAULT, /* default keyring */ password_description, credentials_str, cancellable, &sec_error, "goa-identity", password_key, NULL)) { g_warning ("secret_password_store_sync() failed: %s", sec_error->message); g_set_error_literal (error, GOA_ERROR, GOA_ERROR_FAILED, /* TODO: more specific */ _("Failed to store credentials in the keyring")); g_error_free (sec_error); goto out; } g_debug ("Stored keyring credentials for identity: %s", id); ret = TRUE; out: g_free (credentials_str); g_free (password_key); g_free (password_description); return ret; }
GVariant * goa_utils_lookup_credentials_sync (GoaProvider *provider, GoaObject *object, GCancellable *cancellable, GError **error) { gchar *password_key; GVariant *ret; gchar *password; const gchar *id; GError *sec_error = NULL; g_return_val_if_fail (GOA_IS_PROVIDER (provider), NULL); g_return_val_if_fail (GOA_IS_OBJECT (object) && goa_object_peek_account (object) != NULL, FALSE); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); ret = NULL; password_key = NULL; password = NULL; id = goa_account_get_id (goa_object_peek_account (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)), id); password = secret_password_lookup_sync (&secret_password_schema, cancellable, &sec_error, "goa-identity", password_key, NULL); if (sec_error != NULL) { g_warning ("secret_password_lookup_sync() failed: %s", sec_error->message); g_set_error_literal (error, GOA_ERROR, GOA_ERROR_FAILED, /* TODO: more specific */ _("Failed to retrieve credentials from the keyring")); g_error_free (sec_error); goto out; } else if (password == NULL) { g_warning ("secret_password_lookup_sync() returned NULL"); g_set_error_literal (error, GOA_ERROR, GOA_ERROR_FAILED, /* TODO: more specific */ _("No credentials found in the keyring")); goto out; } g_debug ("Retrieved keyring credentials for id: %s", id); ret = g_variant_parse (NULL, /* GVariantType */ password, NULL, /* limit */ NULL, /* endptr */ error); if (ret == NULL) { g_prefix_error (error, _("Error parsing result obtained from the keyring: ")); goto out; } if (g_variant_is_floating (ret)) g_variant_ref_sink (ret); out: g_free (password); g_free (password_key); return ret; }
static void add_account (GoaPanel *panel) { GtkWindow *parent; GtkWidget *dialog; gint response; GList *providers; GList *l; GoaObject *object; GError *error; providers = NULL; parent = GTK_WINDOW (cc_shell_get_toplevel (cc_panel_get_shell (CC_PANEL (panel)))); dialog = goa_panel_add_account_dialog_new (panel->client); gtk_window_set_transient_for (GTK_WINDOW (dialog), parent); providers = goa_provider_get_all (); for (l = providers; l != NULL; l = l->next) { GoaProvider *provider; provider = GOA_PROVIDER (l->data); goa_panel_add_account_dialog_add_provider (GOA_PANEL_ADD_ACCOUNT_DIALOG (dialog), provider); } gtk_widget_show_all (dialog); response = gtk_dialog_run (GTK_DIALOG (dialog)); if (response != GTK_RESPONSE_OK) { gtk_widget_destroy (dialog); goto out; } error = NULL; object = goa_panel_add_account_dialog_get_account (GOA_PANEL_ADD_ACCOUNT_DIALOG (dialog), &error); gtk_widget_destroy (dialog); /* We might have an object even when error is set. * eg., if we failed to store the credentials in the keyring. */ if (object != NULL) { GtkTreeIter iter; /* navigate to newly created object */ if (goa_panel_accounts_model_get_iter_for_object (panel->accounts_model, object, &iter)) { gtk_tree_selection_select_iter (gtk_tree_view_get_selection (GTK_TREE_VIEW (panel->accounts_treeview)), &iter); } g_object_unref (object); } if (error != NULL) { if (!(error->domain == GOA_ERROR && error->code == GOA_ERROR_DIALOG_DISMISSED)) { dialog = gtk_message_dialog_new (parent, GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, _("Error creating account")); gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", error->message); gtk_widget_show_all (dialog); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); } g_error_free (error); } out: g_list_foreach (providers, (GFunc) g_object_unref, NULL); g_list_free (providers); }