]> git.0d.be Git - empathy.git/commitdiff
event-manager: become an approver for auth channels
authorJonny Lamb <jonnylamb@gnome.org>
Wed, 8 Dec 2010 18:24:21 +0000 (18:24 +0000)
committerJonny Lamb <jonnylamb@gnome.org>
Thu, 9 Dec 2010 16:35:24 +0000 (16:35 +0000)
Signed-off-by: Jonny Lamb <jonnylamb@gnome.org>
src/empathy-event-manager.c
src/empathy-event-manager.h

index 2f947478b6d55d2764284ccfbe38ca16ed043370..9ab20b7698afc6fce22e89fc3751478d610f88e1 100644 (file)
@@ -76,6 +76,7 @@ typedef struct {
 
 typedef struct {
   TpBaseClient *approver;
+  TpBaseClient *auth_approver;
   EmpathyContactManager *contact_manager;
   GSList *events;
   /* Ongoing approvals */
@@ -427,12 +428,47 @@ out:
   g_object_unref (user_data);
 }
 
+static void
+reject_auth_channel_claim_cb (GObject *source,
+    GAsyncResult *result,
+    gpointer user_data)
+{
+  TpChannelDispatchOperation *cdo = TP_CHANNEL_DISPATCH_OPERATION (source);
+  GError *error = NULL;
+
+  if (!tp_channel_dispatch_operation_claim_finish (cdo, result, &error))
+    {
+      DEBUG ("Failed to claim channel: %s", error->message);
+
+      g_error_free (error);
+      return;
+    }
+
+  tp_cli_channel_call_close (TP_CHANNEL (user_data), -1,
+      NULL, NULL, NULL, NULL);
+}
+
 static void
 reject_approval (EventManagerApproval *approval)
 {
   /* We have to claim the channel before closing it */
-  tp_channel_dispatch_operation_claim_async (approval->operation,
-      reject_channel_claim_cb, g_object_ref (approval->handler_instance));
+
+  /* Unfortunately, we need to special case the auth channels for the
+   * time being as they don't have a wrapper object handler in
+   * approval->handler_instance as they're not actually handled by
+   * this process, so we can just use a noddy callback to call Close()
+   * directly. */
+  if (approval->handler_instance != NULL)
+    {
+      tp_channel_dispatch_operation_claim_async (approval->operation,
+          reject_channel_claim_cb, g_object_ref (approval->handler_instance));
+    }
+  else if (tp_channel_get_channel_type_id (approval->main_channel)
+      == TP_IFACE_QUARK_CHANNEL_TYPE_SERVER_AUTHENTICATION)
+    {
+      tp_channel_dispatch_operation_claim_async (approval->operation,
+          reject_auth_channel_claim_cb, approval->main_channel);
+    }
 }
 
 static void
@@ -828,8 +864,13 @@ event_manager_ft_got_contact_cb (TpConnection *connection,
   g_object_unref (window);
 }
 
-/* If there is a file-transfer or media channel consider it as the
- * main one. */
+static void
+dummy_process_func (EventPriv *event)
+{
+}
+
+/* If there is a file-transfer, media, or auth channel consider it as
+ * the main one. */
 static TpChannel *
 find_main_channel (GList *channels)
 {
@@ -847,7 +888,8 @@ find_main_channel (GList *channels)
       channel_type = tp_channel_get_channel_type_id (channel);
 
       if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_STREAMED_MEDIA ||
-          channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_FILE_TRANSFER)
+          channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_FILE_TRANSFER ||
+          channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_SERVER_AUTHENTICATION)
         return channel;
 
       else if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_TEXT)
@@ -971,6 +1013,13 @@ approve_channels (TpSimpleApprover *approver,
       empathy_tp_contact_factory_get_from_handle (connection, handle,
         event_manager_ft_got_contact_cb, approval, NULL, G_OBJECT (self));
     }
+  else if (channel_type == TP_IFACE_QUARK_CHANNEL_TYPE_SERVER_AUTHENTICATION)
+    {
+      /* We need a process function or this will time out after
+       * NOTIFICATION_TIMEOUT seconds, which is undesirable. */
+      event_manager_add (approval->manager, account, NULL, EMPATHY_EVENT_TYPE_AUTH,
+          NULL, NULL, NULL, approval, dummy_process_func, NULL);
+    }
   else
     {
       GError error = { TP_ERRORS, TP_ERROR_INVALID_ARGUMENT,
@@ -1159,6 +1208,7 @@ event_manager_finalize (GObject *object)
   g_slist_free (priv->approvals);
   g_object_unref (priv->contact_manager);
   g_object_unref (priv->approver);
+  g_object_unref (priv->auth_approver);
   g_object_unref (priv->gsettings_notif);
   g_object_unref (priv->gsettings_ui);
   g_object_unref (priv->sound_mgr);
@@ -1200,7 +1250,6 @@ empathy_event_manager_class_init (EmpathyEventManagerClass *klass)
       g_cclosure_marshal_VOID__POINTER,
       G_TYPE_NONE, 1, G_TYPE_POINTER);
 
-
   g_type_class_add_private (object_class, sizeof (EmpathyEventManagerPriv));
 }
 
@@ -1271,12 +1320,41 @@ empathy_event_manager_init (EmpathyEventManager *manager)
         TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_TYPE_CONTACT,
         NULL));
 
+  /* I don't feel good about doing this, and I'm sorry, but the
+   * capabilities connection feature is added earlier because it's
+   * needed for EmpathyTpChat. If the capabilities feature is required
+   * then preparing an auth channel (which of course appears in the
+   * CONNECTING state) will never be prepared. So the options are
+   * either to create another approver like I've done, or to port
+   * EmpathyTpChat and its users to not depend on the connection being
+   * prepared with capabilities. I chose the former, obviously. :-) */
+
+  priv->auth_approver = tp_simple_approver_new (dbus,
+      "Empathy.AuthEventManager", FALSE, approve_channels, manager,
+      NULL);
+
+  /* SASL auth channels */
+  tp_base_client_take_approver_filter (priv->auth_approver,
+      tp_asv_new (
+        TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING,
+          TP_IFACE_CHANNEL_TYPE_SERVER_AUTHENTICATION,
+        TP_PROP_CHANNEL_TYPE_SERVER_AUTHENTICATION_AUTHENTICATION_METHOD,
+          G_TYPE_STRING,
+          TP_IFACE_CHANNEL_INTERFACE_SASL_AUTHENTICATION,
+        NULL));
+
   if (!tp_base_client_register (priv->approver, &error))
     {
       DEBUG ("Failed to register Approver: %s", error->message);
       g_error_free (error);
     }
 
+  if (!tp_base_client_register (priv->auth_approver, &error))
+    {
+      DEBUG ("Failed to register auth Approver: %s", error->message);
+      g_error_free (error);
+    }
+
   g_object_unref (dbus);
 }
 
index d2d1597e156142c9d2935251517cd25829b8ac52..16d97c6dffb06f83fe71716430babf24ae82b31e 100644 (file)
@@ -55,6 +55,7 @@ typedef enum {
     EMPATHY_EVENT_TYPE_SUBSCRIPTION,
     EMPATHY_EVENT_TYPE_PRESENCE,
     EMPATHY_EVENT_TYPE_INVITATION,
+    EMPATHY_EVENT_TYPE_AUTH,
 } EmpathyEventType;
 
 typedef struct {