/**
 * 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 gboolean
on_account_handle_ensure_credentials (GoaAccount            *account,
                                      GDBusMethodInvocation *invocation,
                                      gpointer               user_data)
{
  GoaDaemon *daemon = GOA_DAEMON (user_data);
  GoaProvider *provider;
  GoaObject *object;

  object = GOA_OBJECT (g_dbus_interface_get_object (G_DBUS_INTERFACE (account)));
  provider = goa_provider_get_for_provider_type (goa_account_get_provider_type (account));
  if (provider == NULL)
    {
      g_dbus_method_invocation_return_error (invocation,
                                             GOA_ERROR,
                                             GOA_ERROR_FAILED,
                                             "Unsupported account type %s for id %s (no provider)",
                                             goa_account_get_provider_type (account),
                                             goa_account_get_id (account));
      goto out;
    }

  goa_provider_ensure_credentials (provider,
                                   object,
                                   NULL, /* GCancellable */
                                   (GAsyncReadyCallback) ensure_credentials_cb,
                                   ensure_data_new (daemon, object, invocation));

 out:
  return TRUE; /* invocation was handled */
}
Example #3
0
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;
}
Example #4
0
void
goa_utils_keyfile_set_string (GoaAccount *account, const gchar *key, const gchar *value)
{
  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));

  key_file = g_key_file_new ();
  error = NULL;
  if (!g_key_file_load_from_file (key_file,
                                  path,
                                  G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS,
                                  &error))
    {
      g_warning ("Error loading keyfile %s: %s (%s, %d)",
                 path,
                 error->message,
                 g_quark_to_string (error->domain),
                 error->code);
      g_error_free (error);
      goto out;
    }

  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))
    {
      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);
      goto out;
    }

 out:
  g_free (contents);
  g_key_file_free (key_file);
  g_free (group);
  g_free (path);
}
Example #5
0
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
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 gboolean
on_account_handle_remove (GoaAccount            *account,
                          GDBusMethodInvocation *invocation,
                          gpointer               user_data)
{
  GoaDaemon *daemon = GOA_DAEMON (user_data);
  GoaProvider *provider;
  GKeyFile *key_file;
  const gchar *provider_type;
  gchar *path;
  gchar *group;
  gchar *data;
  gsize length;
  GError *error;

  provider = NULL;
  provider_type = NULL;
  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
   */

  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_key_file_load_from_file (key_file,
                                  path,
                                  G_KEY_FILE_KEEP_COMMENTS,
                                  &error))
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      g_error_free (error);
      goto out;
    }

  group = g_strdup_printf ("Account %s", goa_account_get_id (account));

  error = NULL;
  if (!g_key_file_remove_group (key_file, group, &error))
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      g_error_free (error);
      goto out;
    }

  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_return_gerror (invocation, error);
      goto out;
    }

  error = NULL;
  if (!g_file_set_contents (path,
                            data,
                            length,
                            &error))
    {
      g_prefix_error (&error, "Error writing key-value-file %s: ", path);
      g_dbus_method_invocation_return_gerror (invocation, error);
      goto out;
    }

  provider_type = goa_account_get_provider_type (account);
  if (provider_type == NULL)
    {
      error = NULL;
      g_set_error_literal (&error,
                           GOA_ERROR,
                           GOA_ERROR_FAILED, /* TODO: more specific */
                           _("ProviderType property is not set for account"));
      g_dbus_method_invocation_return_gerror (invocation, error);
      goto out;
    }

  provider = goa_provider_get_for_provider_type (provider_type);
  if (provider == NULL)
    {
      error = NULL;
      g_set_error (&error,
                   GOA_ERROR,
                   GOA_ERROR_FAILED, /* TODO: more specific */
                   _("Failed to find a provider for: %s"),
                   provider_type);
      g_dbus_method_invocation_return_gerror (invocation, error);
      goto out;
    }

  error = NULL;
  if (!goa_utils_delete_credentials_sync (provider, account, NULL, &error))
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      goto out;
    }

  goa_daemon_reload_configuration (daemon);

  goa_account_complete_remove (account, invocation);

 out:
  if (provider != NULL)
    g_object_unref (provider);
  g_free (data);
  if (key_file != NULL)
    g_key_file_free (key_file);
  g_free (group);
  g_free (path);
  return TRUE; /* invocation was handled */
}
Example #8
0
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 gboolean
on_account_handle_remove (GoaAccount            *account,
                          GDBusMethodInvocation *invocation,
                          gpointer               user_data)
{
  GoaDaemon *daemon = GOA_DAEMON (user_data);
  GKeyFile *key_file;
  gchar *path;
  gchar *group;
  gchar *data;
  gsize length;
  GError *error;

  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
   */

  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_key_file_load_from_file (key_file,
                                  path,
                                  G_KEY_FILE_KEEP_COMMENTS,
                                  &error))
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      g_error_free (error);
      goto out;
    }

  group = g_strdup_printf ("Account %s", goa_account_get_id (account));

  error = NULL;
  if (!g_key_file_remove_group (key_file, group, &error))
    {
      g_dbus_method_invocation_return_gerror (invocation, error);
      g_error_free (error);
      goto out;
    }

  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_return_gerror (invocation, error);
      goto out;
    }

  error = NULL;
  if (!g_file_set_contents (path,
                            data,
                            length,
                            &error))
    {
      g_prefix_error (&error, "Error writing key-value-file %s: ", path);
      g_dbus_method_invocation_return_gerror (invocation, error);
      goto out;
    }

  goa_daemon_reload_configuration (daemon);

  goa_account_complete_remove (account, invocation);

 out:
  g_free (data);
  if (key_file != NULL)
    g_key_file_free (key_file);
  g_free (group);
  g_free (path);
  return TRUE; /* invocation was handled */
}