static void ensure_credentials_cb (GoaProvider *provider, GAsyncResult *res, gpointer user_data) { EnsureData *data = user_data; gint expires_in; GError *error; error= NULL; if (!goa_provider_ensure_credentials_finish (provider, &expires_in, res, &error)) { /* Set AttentionNeeded only if the error is an authorization error */ if (is_authorization_error (error)) { GoaAccount *account; account = goa_object_peek_account (data->object); if (!goa_account_get_attention_needed (account)) { goa_account_set_attention_needed (account, TRUE); g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (account)); g_message ("%s: Setting AttentionNeeded to TRUE because EnsureCredentials() failed with: %s (%s, %d)", g_dbus_object_get_object_path (G_DBUS_OBJECT (data->object)), error->message, g_quark_to_string (error->domain), error->code); } } g_dbus_method_invocation_return_gerror (data->invocation, error); g_error_free (error); } else { GoaAccount *account; account = goa_object_peek_account (data->object); /* Clear AttentionNeeded flag if set */ if (goa_account_get_attention_needed (account)) { goa_account_set_attention_needed (account, FALSE); g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (account)); g_message ("%s: Setting AttentionNeeded to FALSE because EnsureCredentials() succeded\n", g_dbus_object_get_object_path (G_DBUS_OBJECT (data->object))); } goa_account_complete_ensure_credentials (goa_object_peek_account (data->object), data->invocation, expires_in); } ensure_data_unref (data); }
static gboolean check_goa_object_match (AddAccountData *data, GoaObject *goa_object) { GoaTelepathyProviderPrivate *priv = data->provider->priv; GoaAccount *goa_account = NULL; const gchar *provider_type = NULL; const gchar *goa_id = NULL; const gchar *tp_id = NULL; if (data->tp_account == NULL) { /* Still waiting for the creation of the TpAccount */ return FALSE; } goa_account = goa_object_peek_account (goa_object); provider_type = goa_account_get_provider_type (goa_account); if (g_strcmp0 (provider_type, priv->provider_type) != 0) return FALSE; /* The backend-specific identity is set to the object path of the * corresponding Telepathy account object. */ goa_id = goa_account_get_identity (goa_account); tp_id = tp_proxy_get_object_path (TP_PROXY (data->tp_account)); if (g_strcmp0 (goa_id, tp_id) == 0) { /* Found it! */ data->ret = g_object_ref (goa_object); g_main_loop_quit (data->loop); return TRUE; } return FALSE; }
/** * goa_client_lookup_by_id: * @client: A #GoaClient. * @id: The ID to look for. * * Finds and returns the #GoaObject instance whose * <link * linkend="gdbus-property-org-gnome-OnlineAccounts-Account.Id">"Id"</link> * D-Bus property matches @id. * * Returns: (transfer full): A #GoaObject. Free the returned * object with g_object_unref(). * * Since: 3.6 */ GoaObject * goa_client_lookup_by_id (GoaClient *client, const gchar *id) { GList *accounts; GList *l; GoaObject *ret; ret = NULL; accounts = goa_client_get_accounts (client); for (l = accounts; l != NULL; l = g_list_next (l)) { GoaAccount *account; GoaObject *object = GOA_OBJECT (l->data); account = goa_object_peek_account (object); if (account == NULL) continue; if (g_strcmp0 (goa_account_get_id (account), id) == 0) { ret = g_object_ref (object); break; } } g_list_free_full (accounts, g_object_unref); return ret; }
static PhotosSharePoint * photos_share_point_manager_create_share_point_online (PhotosSharePointManager *self, PhotosSource *source) { GIOExtension *extension; GType type; GoaAccount *account; GoaObject *object; PhotosSharePoint *ret_val = NULL; const gchar *provider_type; object = photos_source_get_goa_object (source); if (object == NULL) goto out; account = goa_object_peek_account (object); provider_type = goa_account_get_provider_type (account); extension = g_io_extension_point_get_extension_by_name (self->extension_point_online, provider_type); if (extension == NULL) goto out; type = g_io_extension_get_type (extension); ret_val = PHOTOS_SHARE_POINT (g_object_new (type, "source", source, NULL)); out: return ret_val; }
gboolean gfbgraph_goa_authorizer_refresh_authorization (GFBGraphAuthorizer *iface, GCancellable *cancellable, GError **error) { GFBGraphGoaAuthorizerPrivate *priv; GoaAccount *account; GoaOAuth2Based *oauth2_based; gboolean ret_val; priv = GFBGRAPH_GOA_AUTHORIZER_GET_PRIVATE (GFBGRAPH_GOA_AUTHORIZER (iface)); ret_val = FALSE; g_mutex_lock (&priv->mutex); g_free (priv->access_token); priv->access_token = NULL; account = goa_object_peek_account (priv->goa_object); oauth2_based = goa_object_peek_oauth2_based (priv->goa_object); if (goa_account_call_ensure_credentials_sync (account, NULL, cancellable, error)) if (goa_oauth2_based_call_get_access_token_sync (oauth2_based, &priv->access_token, NULL, cancellable, error)) ret_val = TRUE; g_mutex_unlock (&priv->mutex); return ret_val; }
static void on_info_bar_response (GtkInfoBar *info_bar, gint response_id, gpointer user_data) { GoaPanel *panel = GOA_PANEL (user_data); GtkTreeIter iter; if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (panel->accounts_treeview)), NULL, &iter)) { GoaProvider *provider; const gchar *provider_type; GoaAccount *account; GoaObject *object; GtkWindow *parent; GError *error; gtk_tree_model_get (GTK_TREE_MODEL (panel->accounts_model), &iter, GOA_PANEL_ACCOUNTS_MODEL_COLUMN_OBJECT, &object, -1); account = goa_object_peek_account (object); provider_type = goa_account_get_provider_type (account); provider = goa_provider_get_for_provider_type (provider_type); parent = GTK_WINDOW (cc_shell_get_toplevel (cc_panel_get_shell (CC_PANEL (panel)))); error = NULL; if (!goa_provider_refresh_account (provider, panel->client, object, parent, &error)) { if (!(error->domain == GOA_ERROR && error->code == GOA_ERROR_DIALOG_DISMISSED)) { GtkWidget *dialog; dialog = gtk_message_dialog_new (parent, GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, _("Error logging into the 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); } g_object_unref (provider); g_object_unref (object); } }
gboolean goa_utils_check_duplicate (GoaClient *client, const gchar *identity, const gchar *presentation_identity, const gchar *provider_type, GoaPeekInterfaceFunc func, GError **error) { GList *accounts; GList *l; gboolean ret; ret = FALSE; accounts = goa_client_get_accounts (client); for (l = accounts; l != NULL; l = l->next) { GoaObject *object = GOA_OBJECT (l->data); GoaAccount *account; gpointer *interface; const gchar *identity_from_object; const gchar *presentation_identity_from_object; const gchar *provider_type_from_object; account = goa_object_peek_account (object); interface = (*func) (object); if (interface == NULL) continue; provider_type_from_object = goa_account_get_provider_type (account); if (g_strcmp0 (provider_type_from_object, provider_type) != 0) continue; identity_from_object = goa_account_get_identity (account); presentation_identity_from_object = goa_account_get_presentation_identity (account); if (g_strcmp0 (identity_from_object, identity) == 0 && g_strcmp0 (presentation_identity_from_object, presentation_identity) == 0) { const gchar *provider_name; provider_name = goa_account_get_provider_name (account); g_set_error (error, GOA_ERROR, GOA_ERROR_ACCOUNT_EXISTS, _("A %s account already exists for %s"), provider_name, presentation_identity); goto out; } } ret = TRUE; out: g_list_free_full (accounts, g_object_unref); return ret; }
gboolean goa_utils_store_credentials_for_object_sync (GoaProvider *provider, GoaObject *object, GVariant *credentials, GCancellable *cancellable, GError **error) { const gchar *id; g_return_val_if_fail (GOA_IS_PROVIDER (provider), FALSE); g_return_val_if_fail (GOA_IS_OBJECT (object) && goa_object_peek_account (object) != NULL, 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); id = goa_account_get_id (goa_object_peek_account (object)); return goa_utils_store_credentials_for_id_sync (provider, id, credentials, cancellable, error); }
static void on_object_removed (GDBusObjectManager *manager, GDBusObject *object, gpointer user_data) { GoaClient *client = GOA_CLIENT (user_data); if (goa_object_peek_account (GOA_OBJECT (object)) != NULL) g_signal_emit (client, signals[ACCOUNT_REMOVED_SIGNAL], 0, object); }
static void on_interface_added (GDBusObjectManager *manager, GDBusObject *object, GDBusInterface *interface, gpointer user_data) { GoaClient *client = GOA_CLIENT (user_data); if (goa_object_peek_account (GOA_OBJECT (object)) != NULL) g_signal_emit (client, signals[ACCOUNT_CHANGED_SIGNAL], 0, object); }
static void on_interface_proxy_properties_changed (GDBusObjectManagerClient *manager, GDBusObjectProxy *object_proxy, GDBusProxy *interface_proxy, GVariant *changed_properties, const gchar* const *invalidated_properties, gpointer user_data) { GoaClient *client = GOA_CLIENT (user_data); if (goa_object_peek_account (GOA_OBJECT (object_proxy)) != NULL) g_signal_emit (client, signals[ACCOUNT_CHANGED_SIGNAL], 0, object_proxy); }
static gboolean on_handle_get_password (GoaPasswordBased *interface, GDBusMethodInvocation *invocation, const gchar *id, gpointer user_data) { GoaObject *object; GoaAccount *account; GoaProvider *provider; GError *error; GVariant *credentials; gchar *password; /* TODO: maybe log what app is requesting access */ password = NULL; credentials = NULL; object = GOA_OBJECT (g_dbus_interface_get_object (G_DBUS_INTERFACE (interface))); account = goa_object_peek_account (object); provider = goa_provider_get_for_provider_type (goa_account_get_provider_type (account)); error = NULL; credentials = goa_utils_lookup_credentials_sync (provider, object, NULL, /* GCancellable* */ &error); if (credentials == NULL) { g_dbus_method_invocation_take_error (invocation, error); goto out; } if (!g_variant_lookup (credentials, "password", "s", &password)) { g_dbus_method_invocation_return_error (invocation, GOA_ERROR, GOA_ERROR_FAILED, /* TODO: more specific */ _("Did not find password with username `%s' in credentials"), id); goto out; } goa_password_based_complete_get_password (interface, invocation, password); out: g_free (password); if (credentials != NULL) g_variant_unref (credentials); g_object_unref (provider); return TRUE; /* invocation was handled */ }
static TpAccount * find_tp_account (GoaObject *goa_object, GMainLoop *loop, GError **out_error) { GoaAccount *goa_account = NULL; const gchar *id = NULL; TpAccountManager *account_manager; GList *tp_accounts = NULL; GList *l = NULL; TpAccount *tp_account = NULL; GError *error = NULL; goa_account = goa_object_peek_account (goa_object); id = goa_account_get_identity (goa_account); account_manager = tp_account_manager_dup (); if (!prepare_tp_proxy (account_manager, NULL, loop, &error)) goto out; tp_accounts = tp_account_manager_dup_valid_accounts (account_manager); for (l = tp_accounts; l != NULL; l = l->next) { if (g_strcmp0 (tp_proxy_get_object_path (l->data), id) == 0) { tp_account = g_object_ref (l->data); break; } } if (tp_account == NULL) { g_set_error (&error, GOA_ERROR, GOA_ERROR_FAILED, _("Telepathy chat account not found")); goto out; } out: if (error != NULL) g_propagate_error (out_error, error); g_clear_error (&error); g_clear_object (&account_manager); g_list_free_full (tp_accounts, g_object_unref); return tp_account; }
static void on_toolbar_remove_button_clicked (GtkToolButton *button, gpointer user_data) { GoaPanel *panel = GOA_PANEL (user_data); GtkTreeIter iter; if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (panel->accounts_treeview)), NULL, &iter)) { GoaObject *object; GtkWidget *dialog; gint response; gtk_tree_model_get (GTK_TREE_MODEL (panel->accounts_model), &iter, GOA_PANEL_ACCOUNTS_MODEL_COLUMN_OBJECT, &object, -1); dialog = gtk_message_dialog_new (GTK_WINDOW (cc_shell_get_toplevel (cc_panel_get_shell (CC_PANEL (panel)))), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_CANCEL, _("Are you sure you want to remove the account?")); gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), _("This will not remove the account on the server.")); gtk_dialog_add_button (GTK_DIALOG (dialog), _("_Remove"), GTK_RESPONSE_OK); gtk_widget_show_all (dialog); response = gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); if (response == GTK_RESPONSE_OK) { goa_account_call_remove (goa_object_peek_account (object), NULL, /* GCancellable */ (GAsyncReadyCallback) remove_account_cb, g_object_ref (panel)); } g_object_unref (object); } }
static void gfbgraph_goa_authorizer_set_goa_object (GFBGraphGoaAuthorizer *self, GoaObject *goa_object) { GoaAccount *account; GoaOAuth2Based *oauth2_based; GFBGraphGoaAuthorizerPrivate *priv; g_return_if_fail (GOA_IS_OBJECT (goa_object)); priv = GFBGRAPH_GOA_AUTHORIZER_GET_PRIVATE (self); oauth2_based = goa_object_peek_oauth2_based (goa_object); g_return_if_fail (oauth2_based != NULL && GOA_IS_OAUTH2_BASED (oauth2_based)); account = goa_object_peek_account (goa_object); g_return_if_fail (account != NULL && GOA_IS_ACCOUNT (account)); g_object_ref (goa_object); priv->goa_object = goa_object; }
static void photos_source_manager_refresh_accounts (PhotosSourceManager *self) { PhotosSourceManagerPrivate *priv = self->priv; GHashTable *new_sources; GList *accounts; GList *l; accounts = goa_client_get_accounts (priv->client); new_sources = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); for (l = accounts; l != NULL; l = l->next) { GoaAccount *account; GoaObject *object = GOA_OBJECT (l->data); PhotosSource *source; const gchar *id; account = goa_object_peek_account (object); if (account == NULL) continue; if (goa_account_get_photos_disabled (account)) continue; if (goa_object_peek_photos (object) == NULL) continue; source = photos_source_new_from_goa_object (GOA_OBJECT (l->data)); id = photos_filterable_get_id (PHOTOS_FILTERABLE (source)); g_hash_table_insert (new_sources, g_strdup (id), g_object_ref (source)); g_object_unref (source); } photos_base_manager_process_new_objects (PHOTOS_BASE_MANAGER (self), new_sources); g_hash_table_unref (new_sources); g_list_free_full (accounts, g_object_unref); }
/** * goa_client_get_accounts: * @client: A #GoaClient. * * Gets all accounts that @client knows about. The result is a list of * #GoaObject instances where each object at least has an #GoaAccount * interface (that can be obtained via the goa_object_get_account() * method) but may also implement other interfaces such as * #GoaMail or #GoaFiles. * * Returns: (transfer full) (element-type GoaObject): A list of * #GoaObject instances that must be freed with g_list_free() after * each element has been freed with g_object_unref(). */ GList * goa_client_get_accounts (GoaClient *client) { GList *ret; GList *objects; GList *l; g_return_val_if_fail (GOA_IS_CLIENT (client), NULL); ret = NULL; objects = g_dbus_object_manager_get_objects (client->object_manager); for (l = objects; l != NULL; l = l->next) { GoaObject *object = GOA_OBJECT (l->data); if (goa_object_peek_account (object) != NULL) ret = g_list_prepend (ret, g_object_ref (object)); } g_list_foreach (objects, (GFunc) g_object_unref, NULL); g_list_free (objects); return ret; }
static void set_values (GoaPanelAccountsModel *model, GoaObject *object, GtkTreeIter *iter) { GoaAccount *account; GIcon *icon; gchar *markup; GError *error; account = goa_object_peek_account (object); error = NULL; icon = g_icon_new_for_string (goa_account_get_provider_icon (account), &error); if (icon == NULL) { goa_warning ("Error creating GIcon for account: %s (%s, %d)", error->message, g_quark_to_string (error->domain), error->code); g_error_free (error); } markup = g_strdup_printf ("<b>%s</b>\n<small>%s</small>", goa_account_get_provider_name (account), goa_account_get_presentation_identity (account)); gtk_list_store_set (GTK_LIST_STORE (model), iter, GOA_PANEL_ACCOUNTS_MODEL_COLUMN_SORT_KEY, goa_account_get_id (account), GOA_PANEL_ACCOUNTS_MODEL_COLUMN_OBJECT, object, GOA_PANEL_ACCOUNTS_MODEL_COLUMN_ATTENTION_NEEDED, goa_account_get_attention_needed (account), GOA_PANEL_ACCOUNTS_MODEL_COLUMN_MARKUP, markup, GOA_PANEL_ACCOUNTS_MODEL_COLUMN_ICON, icon, -1); g_free (markup); g_clear_object (&icon); }
static void show_page_account (GoaPanel *panel, GoaObject *object) { GList *children; GList *l; GtkWidget *box; GtkWidget *grid; GtkWidget *left_grid; GtkWidget *right_grid; GtkWidget *bar; GtkWidget *label; GoaProvider *provider; GoaAccount *account; const gchar *provider_type; provider = NULL; show_page (panel, 1); box = GTK_WIDGET (gtk_builder_get_object (panel->builder, "accounts-tree-box")); gtk_widget_set_sensitive (box, TRUE); label = GTK_WIDGET (gtk_builder_get_object (panel->builder, "accounts-tree-label")); gtk_widget_hide (label); /* Out with the old */ children = gtk_container_get_children (GTK_CONTAINER (panel->accounts_vbox)); for (l = children; l != NULL; l = l->next) gtk_container_remove (GTK_CONTAINER (panel->accounts_vbox), GTK_WIDGET (l->data)); g_list_free (children); account = goa_object_peek_account (object); provider_type = goa_account_get_provider_type (account); provider = goa_provider_get_for_provider_type (provider_type); /* And in with the new */ if (goa_account_get_attention_needed (account)) { bar = gtk_info_bar_new (); label = gtk_label_new (_("Expired credentials. Please log in again.")); gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (bar))), label); if (provider != NULL) gtk_info_bar_add_button (GTK_INFO_BAR (bar), _("_Log In"), GTK_RESPONSE_OK); gtk_box_pack_start (GTK_BOX (panel->accounts_vbox), bar, FALSE, TRUE, 0); g_signal_connect (bar, "response", G_CALLBACK (on_info_bar_response), panel); } left_grid = gtk_grid_new (); gtk_widget_set_halign (left_grid, GTK_ALIGN_END); gtk_widget_set_hexpand (left_grid, TRUE); gtk_orientable_set_orientation (GTK_ORIENTABLE (left_grid), GTK_ORIENTATION_VERTICAL); gtk_grid_set_row_spacing (GTK_GRID (left_grid), 0); right_grid = gtk_grid_new (); gtk_widget_set_hexpand (right_grid, TRUE); gtk_orientable_set_orientation (GTK_ORIENTABLE (right_grid), GTK_ORIENTATION_VERTICAL); gtk_grid_set_row_spacing (GTK_GRID (right_grid), 0); if (provider != NULL) { goa_provider_show_account (provider, panel->client, object, GTK_BOX (panel->accounts_vbox), GTK_GRID (left_grid), GTK_GRID (right_grid)); } grid = gtk_grid_new (); gtk_orientable_set_orientation (GTK_ORIENTABLE (grid), GTK_ORIENTATION_HORIZONTAL); gtk_grid_set_column_spacing (GTK_GRID (grid), 12); gtk_container_add (GTK_CONTAINER (grid), left_grid); gtk_container_add (GTK_CONTAINER (grid), right_grid); gtk_box_pack_start (GTK_BOX (panel->accounts_vbox), grid, FALSE, TRUE, 0); gtk_widget_show_all (panel->accounts_vbox); if (provider != NULL) g_object_unref (provider); }
gint main (void) { GDataDocumentsFeed *feed = NULL; GDataDocumentsQuery *query = NULL; GDataDocumentsService *service = NULL; GError *error = NULL; GList *accounts = NULL; GList *entries; GList *l; GoaClient *client = NULL; client = goa_client_new_sync (NULL, &error); if (error != NULL) { g_warning ("%s", error->message); g_error_free (error); goto out; } accounts = goa_client_get_accounts (client); for (l = accounts; l != NULL; l = l->next) { GoaAccount *account; GoaObject *object = GOA_OBJECT (l->data); const gchar *provider_type; account = goa_object_peek_account (object); provider_type = goa_account_get_provider_type (account); if (g_strcmp0 (provider_type, "google") == 0) { GDataGoaAuthorizer *authorizer; authorizer = gdata_goa_authorizer_new (object); service = gdata_documents_service_new (GDATA_AUTHORIZER (authorizer)); g_object_unref (authorizer); } } if (service == NULL) { g_warning ("Account not found"); goto out; } query = gdata_documents_query_new_with_limits (NULL, 1, 10); gdata_documents_query_set_show_folders (query, TRUE); while (TRUE) { feed = gdata_documents_service_query_documents (service, query, NULL, NULL, NULL, &error); if (error != NULL) { g_warning ("%s", error->message); g_error_free (error); goto out; } entries = gdata_feed_get_entries (GDATA_FEED (feed)); if (entries == NULL) { goto out; } for (l = entries; l != NULL; l = l->next) { GDataEntry *entry = GDATA_ENTRY (l->data); const gchar *title; title = gdata_entry_get_title (entry); g_message ("%s", title); } gdata_query_next_page (GDATA_QUERY (query)); g_object_unref (feed); } out: g_clear_object (&feed); g_clear_object (&query); g_clear_object (&service); g_clear_object (&client); g_list_free_full (accounts, g_object_unref); return 0; }
static gboolean ensure_credentials_sync (GoaProvider *provider, GoaObject *object, gint *out_expires_in, GCancellable *cancellable, GError **error) { GVariant *credentials; GoaAccount *account; GoaEwsClient *ews_client; GoaExchange *exchange; gboolean accept_ssl_errors; gboolean ret; const gchar *email_address; const gchar *server; const gchar *username; gchar *password; credentials = NULL; ews_client = NULL; password = NULL; ret = FALSE; credentials = goa_utils_lookup_credentials_sync (provider, object, cancellable, error); if (credentials == NULL) { if (error != NULL) { g_prefix_error (error, _("Credentials not found in keyring (%s, %d): "), g_quark_to_string ((*error)->domain), (*error)->code); (*error)->domain = GOA_ERROR; (*error)->code = GOA_ERROR_NOT_AUTHORIZED; } goto out; } account = goa_object_peek_account (object); email_address = goa_account_get_presentation_identity (account); username = goa_account_get_identity (account); if (!g_variant_lookup (credentials, "password", "s", &password)) { if (error != NULL) { *error = g_error_new (GOA_ERROR, GOA_ERROR_NOT_AUTHORIZED, _("Did not find password with username `%s' in credentials"), username); } goto out; } exchange = goa_object_peek_exchange (object); accept_ssl_errors = goa_util_lookup_keyfile_boolean (object, "AcceptSslErrors"); server = goa_exchange_get_host (exchange); ews_client = goa_ews_client_new (); ret = goa_ews_client_autodiscover_sync (ews_client, email_address, password, username, server, accept_ssl_errors, cancellable, error); if (!ret) { if (error != NULL) { g_prefix_error (error, /* Translators: the first %s is the username * (eg., [email protected] or rishi), and the * (%s, %d) is the error domain and code. */ _("Invalid password with username `%s' (%s, %d): "), username, g_quark_to_string ((*error)->domain), (*error)->code); (*error)->domain = GOA_ERROR; (*error)->code = GOA_ERROR_NOT_AUTHORIZED; } goto out; } if (out_expires_in != NULL) *out_expires_in = 0; out: if (ews_client != NULL) g_object_unref (ews_client); g_free (password); if (credentials != NULL) g_variant_unref (credentials); return ret; }
static gboolean refresh_account (GoaProvider *provider, GoaClient *client, GoaObject *object, GtkWindow *parent, GError **error) { AddAccountData data; GVariantBuilder builder; GoaAccount *account; GoaEwsClient *ews_client; GoaExchange *exchange; GtkWidget *dialog; GtkWidget *vbox; gboolean accept_ssl_errors; gboolean ret; const gchar *email_address; const gchar *server; const gchar *password; const gchar *username; gint response; g_return_val_if_fail (GOA_IS_EXCHANGE_PROVIDER (provider), FALSE); g_return_val_if_fail (GOA_IS_CLIENT (client), FALSE); g_return_val_if_fail (GOA_IS_OBJECT (object), FALSE); g_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); ews_client = NULL; ret = FALSE; dialog = gtk_dialog_new_with_buttons (NULL, parent, GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL); gtk_container_set_border_width (GTK_CONTAINER (dialog), 12); gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); vbox = gtk_dialog_get_content_area (GTK_DIALOG (dialog)); gtk_box_set_spacing (GTK_BOX (vbox), 12); memset (&data, 0, sizeof (AddAccountData)); data.loop = g_main_loop_new (NULL, FALSE); data.dialog = GTK_DIALOG (dialog); data.error = NULL; create_account_details_ui (provider, GTK_DIALOG (dialog), GTK_BOX (vbox), FALSE, &data); account = goa_object_peek_account (object); email_address = goa_account_get_presentation_identity (account); gtk_entry_set_text (GTK_ENTRY (data.email_address), email_address); gtk_editable_set_editable (GTK_EDITABLE (data.email_address), FALSE); gtk_widget_show_all (dialog); ews_client = goa_ews_client_new (); ews_again: response = gtk_dialog_run (GTK_DIALOG (dialog)); if (response != GTK_RESPONSE_OK) { g_set_error (error, GOA_ERROR, GOA_ERROR_DIALOG_DISMISSED, _("Dialog was dismissed")); goto out; } password = gtk_entry_get_text (GTK_ENTRY (data.password)); username = goa_account_get_identity (account); exchange = goa_object_peek_exchange (object); accept_ssl_errors = goa_util_lookup_keyfile_boolean (object, "AcceptSslErrors"); server = goa_exchange_get_host (exchange); goa_ews_client_autodiscover (ews_client, email_address, password, username, server, accept_ssl_errors, NULL, autodiscover_cb, &data); goa_spinner_button_start (GOA_SPINNER_BUTTON (data.spinner_button)); g_main_loop_run (data.loop); if (data.error != NULL) { GtkWidget *button; gchar *markup; markup = g_strdup_printf ("<b>%s:</b> %s", _("Error connecting to Microsoft Exchange server"), data.error->message); g_clear_error (&data.error); gtk_label_set_markup (GTK_LABEL (data.cluebar_label), markup); g_free (markup); button = gtk_dialog_get_widget_for_response (data.dialog, GTK_RESPONSE_OK); gtk_button_set_label (GTK_BUTTON (button), _("_Try Again")); gtk_widget_set_no_show_all (data.cluebar, FALSE); gtk_widget_show_all (data.cluebar); goto ews_again; } /* TODO: run in worker thread */ g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); g_variant_builder_add (&builder, "{sv}", "password", g_variant_new_string (password)); if (!goa_utils_store_credentials_for_object_sync (provider, object, g_variant_builder_end (&builder), NULL, /* GCancellable */ error)) goto out; goa_account_call_ensure_credentials (account, NULL, /* GCancellable */ NULL, NULL); /* callback, user_data */ ret = TRUE; out: gtk_widget_destroy (dialog); if (data.loop != NULL) g_main_loop_unref (data.loop); if (ews_client != NULL) g_object_unref (ews_client); return ret; }
static void goa_daemon_update_notifications (GoaDaemon *daemon) { gboolean show_notification; GList *objects; GList *l; show_notification = FALSE; objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (daemon->object_manager)); for (l = objects; l != NULL; l = l->next) { GoaObject *object = GOA_OBJECT (l->data); GoaAccount *account; account = goa_object_peek_account (object); if (account != NULL) { if (goa_account_get_attention_needed (account)) { show_notification = TRUE; break; } } } if (show_notification) { if (daemon->notification == NULL) { GError *error; daemon->notification = notify_notification_new (_("An online account needs attention"), NULL, NULL); notify_notification_set_timeout (daemon->notification, NOTIFY_EXPIRES_NEVER); g_object_set (daemon->notification, "icon-name", "gtk-dialog-error", NULL); notify_notification_add_action (daemon->notification, "open-online-accounts", _("Open Online Accounts..."), notification_cb, daemon, NULL); /* GFreeFunc */ error = NULL; if (!notify_notification_show (daemon->notification, &error)) { goa_warning ("Error showing notification: %s (%s, %d)", error->message, g_quark_to_string (error->domain), error->code); g_error_free (error); g_object_unref (daemon->notification); daemon->notification = NULL; } else { g_signal_connect (daemon->notification, "closed", G_CALLBACK (on_notification_closed), daemon); } } } else { if (daemon->notification != NULL) { GError *error; error = NULL; if (!notify_notification_close (daemon->notification, &error)) { goa_warning ("Error closing notification: %s (%s, %d)", error->message, g_quark_to_string (error->domain), error->code); g_error_free (error); } g_signal_handlers_disconnect_by_func (daemon->notification, G_CALLBACK (on_notification_closed), daemon); g_object_unref (daemon->notification); daemon->notification = NULL; } } g_list_foreach (objects, (GFunc) g_object_unref, NULL); g_list_free (objects); }
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 process_config_entries (GoaDaemon *daemon, GHashTable *group_name_to_key_file_data) { GHashTableIter iter; const gchar *id; KeyFileData *key_file_data; GList *existing_object_paths; GList *config_object_paths; GList *added; GList *removed; GList *unchanged; GList *l; existing_object_paths = NULL; { GList *existing_objects; existing_objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (daemon->object_manager)); for (l = existing_objects; l != NULL; l = l->next) { GoaObject *object = GOA_OBJECT (l->data); const gchar *object_path; object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (object)); if (g_str_has_prefix (object_path, "/org/gnome/OnlineAccounts/Accounts/")) existing_object_paths = g_list_prepend (existing_object_paths, g_strdup (object_path)); } g_list_foreach (existing_objects, (GFunc) g_object_unref, NULL); g_list_free (existing_objects); } 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)) { 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)) { g_warning ("`%s' is not a valid account identifier", id); g_free (object_path); continue; } /* steals object_path variable */ config_object_paths = g_list_prepend (config_object_paths, object_path); } existing_object_paths = g_list_sort (existing_object_paths, (GCompareFunc) g_strcmp0); config_object_paths = g_list_sort (config_object_paths, (GCompareFunc) g_strcmp0); diff_sorted_lists (existing_object_paths, config_object_paths, (GCompareFunc) g_strcmp0, &added, &removed, &unchanged); for (l = removed; l != NULL; l = l->next) { const gchar *object_path = l->data; GoaObject *object; object = GOA_OBJECT (g_dbus_object_manager_get_object (G_DBUS_OBJECT_MANAGER (daemon->object_manager), object_path)); g_warn_if_fail (object != NULL); g_signal_handlers_disconnect_by_func (goa_object_peek_account (object), G_CALLBACK (on_account_handle_remove), daemon); g_debug ("removing %s", object_path); g_warn_if_fail (g_dbus_object_manager_server_unexport (daemon->object_manager, object_path)); } for (l = added; l != NULL; l = l->next) { const gchar *object_path = l->data; GoaObjectSkeleton *object; gchar *group; g_debug ("adding %s", object_path); group = object_path_to_group (object_path); key_file_data = g_hash_table_lookup (group_name_to_key_file_data, group); g_warn_if_fail (key_file_data != NULL); object = goa_object_skeleton_new (object_path); if (update_account_object (daemon, object, key_file_data->path, group, key_file_data->key_file, TRUE)) { g_dbus_object_manager_server_export (daemon->object_manager, G_DBUS_OBJECT_SKELETON (object)); g_signal_connect (goa_object_peek_account (GOA_OBJECT (object)), "handle-remove", G_CALLBACK (on_account_handle_remove), daemon); g_signal_connect (goa_object_peek_account (GOA_OBJECT (object)), "handle-ensure-credentials", G_CALLBACK (on_account_handle_ensure_credentials), daemon); } g_object_unref (object); g_free (group); } for (l = unchanged; l != NULL; l = l->next) { const gchar *object_path = l->data; GoaObject *object; gchar *group; g_debug ("unchanged %s", object_path); group = object_path_to_group (object_path); key_file_data = g_hash_table_lookup (group_name_to_key_file_data, group); g_warn_if_fail (key_file_data != NULL); object = GOA_OBJECT (g_dbus_object_manager_get_object (G_DBUS_OBJECT_MANAGER (daemon->object_manager), object_path)); g_warn_if_fail (object != NULL); if (!update_account_object (daemon, GOA_OBJECT_SKELETON (object), key_file_data->path, group, key_file_data->key_file, FALSE)) { g_signal_handlers_disconnect_by_func (goa_object_peek_account (object), G_CALLBACK (on_account_handle_remove), daemon); g_signal_handlers_disconnect_by_func (goa_object_peek_account (object), G_CALLBACK (on_account_handle_ensure_credentials), daemon); g_warn_if_fail (g_dbus_object_manager_server_unexport (daemon->object_manager, object_path)); } g_object_unref (object); g_free (group); } g_list_free (removed); g_list_free (added); g_list_free (unchanged); g_list_foreach (existing_object_paths, (GFunc) g_free, NULL); g_list_free (existing_object_paths); g_list_foreach (config_object_paths, (GFunc) g_free, NULL); g_list_free (config_object_paths); }