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;
}
예제 #2
0
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;
}
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 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 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;
}