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 gchar *
smtp_auth_get_password (GoaSmtpAuth       *self,
                        GCancellable      *cancellable,
                        GError           **error)
{
  gchar *password;

  password = NULL;

  if (self->password != NULL)
    {
      password = g_strdup (self->password);
    }
  else if (self->provider != NULL && self->object != NULL)
    {
      GVariant *credentials;
      credentials = goa_utils_lookup_credentials_sync (self->provider,
                                                       self->object,
                                                       cancellable,
                                                       error);
      if (credentials == NULL)
        {
          g_prefix_error (error, "Error looking up credentials for SMTP in keyring: ");
          goto out;
        }
      if (!g_variant_lookup (credentials, "smtp-password", "s", &password))
        {
          g_set_error (error,
                       GOA_ERROR,
                       GOA_ERROR_FAILED, /* TODO: more specific */
                       _("Did not find smtp-password in credentials"));
          g_variant_unref (credentials);
          goto out;
        }
      g_variant_unref (credentials);
    }
  else
    {
      g_set_error (error,
                   GOA_ERROR,
                   GOA_ERROR_FAILED, /* TODO: more specific */
                   _("Cannot do SMTP authentication without a password"));
      goto out;
    }

 out:
  return password;
}
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;
}