]> git.0d.be Git - empathy.git/blobdiff - libempathy/empathy-sasl-mechanisms.c
Center the 'smiley images' inside the menu items
[empathy.git] / libempathy / empathy-sasl-mechanisms.c
index 2857c8b6ac256d92ffc20e5f80924cda3021310a..05a2de97a16233dfab6bfcef7ae35b26689ce9cb 100644 (file)
  */
 
 #include "config.h"
+#include "empathy-sasl-mechanisms.h"
 
 #include <libsoup/soup.h>
-#include <string.h>
+#include <tp-account-widgets/tpaw-utils.h>
+#include <telepathy-glib/telepathy-glib-dbus.h>
 
 #define DEBUG_FLAG EMPATHY_DEBUG_SASL
 #include "empathy-debug.h"
 #include "empathy-utils.h"
-#include "empathy-sasl-mechanisms.h"
 
 #define MECH_FACEBOOK "X-FACEBOOK-PLATFORM"
 #define MECH_WLM "X-MESSENGER-OAUTH2"
 #define MECH_GOOGLE "X-OAUTH2"
+#define MECH_PASSWORD "X-TELEPATHY-PASSWORD"
 
 typedef struct
 {
@@ -42,6 +44,10 @@ static SupportedMech supported_mechanisms[] = {
   { EMPATHY_SASL_MECHANISM_FACEBOOK, MECH_FACEBOOK },
   { EMPATHY_SASL_MECHANISM_WLM, MECH_WLM },
   { EMPATHY_SASL_MECHANISM_GOOGLE, MECH_GOOGLE },
+
+  /* Must be the last one, otherwise empathy_sasl_channel_select_mechanism()
+   * will prefer password over web auth for servers supporting both. */
+  { EMPATHY_SASL_MECHANISM_PASSWORD, MECH_PASSWORD }
 };
 
 static void
@@ -150,8 +156,7 @@ facebook_new_challenge_cb (TpChannel *channel,
   GSimpleAsyncResult *result = user_data;
   FacebookData *data;
   GHashTable *h;
-  GHashTable *params;
-  gchar *response;
+  GString *response_string;
   GArray *response_array;
 
   DEBUG ("new challenge: %s", challenge->data);
@@ -160,27 +165,29 @@ facebook_new_challenge_cb (TpChannel *channel,
 
   h = soup_form_decode (challenge->data);
 
-  /* See https://developers.facebook.com/docs/chat/#platauth */
-  params = g_hash_table_new (g_str_hash, g_str_equal);
-  g_hash_table_insert (params, "method", g_hash_table_lookup (h, "method"));
-  g_hash_table_insert (params, "nonce", g_hash_table_lookup (h, "nonce"));
-  g_hash_table_insert (params, "access_token", data->access_token);
-  g_hash_table_insert (params, "api_key", data->client_id);
-  g_hash_table_insert (params, "call_id", "0");
-  g_hash_table_insert (params, "v", "1.0");
-
-  response = soup_form_encode_hash (params);
-  DEBUG ("Response: %s", response);
+  /* See https://developers.facebook.com/docs/chat/#platauth.
+   * We don't use soup_form_encode() here because it would escape parameters
+   * and facebook server is not expecting that and would reject the response. */
+  response_string = g_string_new ("v=1.0&call_id=0");
+  g_string_append (response_string, "&access_token=");
+  g_string_append_uri_escaped (response_string, data->access_token, NULL, TRUE);
+  g_string_append (response_string, "&api_key=");
+  g_string_append_uri_escaped (response_string, data->client_id, NULL, TRUE);
+  g_string_append (response_string, "&method=");
+  g_string_append_uri_escaped (response_string, g_hash_table_lookup (h, "method"), NULL, TRUE);
+  g_string_append (response_string, "&nonce=");
+  g_string_append_uri_escaped (response_string, g_hash_table_lookup (h, "nonce"), NULL, TRUE);
+
+  DEBUG ("Response: %s", response_string->str);
 
   response_array = g_array_new (FALSE, FALSE, sizeof (gchar));
-  g_array_append_vals (response_array, response, strlen (response));
+  g_array_append_vals (response_array, response_string->str, response_string->len);
 
   tp_cli_channel_interface_sasl_authentication_call_respond (data->channel, -1,
       response_array, generic_cb, g_object_ref (result), g_object_unref, NULL);
 
   g_hash_table_unref (h);
-  g_hash_table_unref (params);
-  g_free (response);
+  g_string_free (response_string, TRUE);
   g_array_unref (response_array);
 }
 
@@ -297,27 +304,64 @@ empathy_sasl_auth_google_async (TpChannel *channel,
   g_object_unref (result);
 }
 
+void
+empathy_sasl_auth_password_async (TpChannel *channel,
+    const gchar *password,
+    GAsyncReadyCallback callback,
+    gpointer user_data)
+{
+  GSimpleAsyncResult *result;
+  GArray *password_array;
+
+  result = empathy_sasl_auth_common_async (channel, callback, user_data);
+
+  g_return_if_fail (result != NULL);
+  g_return_if_fail (empathy_sasl_channel_supports_mechanism (channel,
+      MECH_PASSWORD));
+  g_return_if_fail (!tp_str_empty (password));
+
+  DEBUG ("Start %s mechanism", MECH_PASSWORD);
+
+  password_array = g_array_sized_new (FALSE, FALSE, sizeof (gchar),
+      strlen (password));
+  g_array_append_vals (password_array, password, strlen (password));
+
+  tp_cli_channel_interface_sasl_authentication_call_start_mechanism_with_data (
+      channel, -1, MECH_PASSWORD, password_array,
+      generic_cb, g_object_ref (result), g_object_unref, NULL);
+
+  g_array_unref (password_array);
+  g_object_unref (result);
+}
+
 gboolean
 empathy_sasl_auth_finish (TpChannel *channel,
     GAsyncResult *result,
     GError **error)
 {
-  empathy_implement_finish_void (channel, empathy_sasl_auth_common_async);
+  tpaw_implement_finish_void (channel, empathy_sasl_auth_common_async);
 }
 
 gboolean
 empathy_sasl_channel_supports_mechanism (TpChannel *channel,
     const gchar *mechanism)
 {
-  GHashTable *props;
-  const gchar * const *available_mechanisms;
+  GVariant *props;
+  GStrv available_mechanisms;
+  gboolean result;
 
-  props = tp_channel_borrow_immutable_properties (channel);
-  available_mechanisms = tp_asv_get_boxed (props,
+  props = tp_channel_dup_immutable_properties (channel);
+
+  g_variant_lookup (props,
       TP_PROP_CHANNEL_INTERFACE_SASL_AUTHENTICATION_AVAILABLE_MECHANISMS,
-      G_TYPE_STRV);
+      "^as", &available_mechanisms);
+
+  result = tp_strv_contains ((const gchar * const *) available_mechanisms,
+      mechanism);
 
-  return tp_strv_contains (available_mechanisms, mechanism);
+  g_variant_unref (props);
+  g_strfreev (available_mechanisms);
+  return result;
 }
 
 EmpathySaslMechanism