summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonny Lamb <jonnylamb@gnome.org>2010-12-08 18:24:21 +0000
committerJonny Lamb <jonnylamb@gnome.org>2010-12-09 16:35:24 +0000
commit071992a0704d43baa2a72b576401ea1f68b44de6 (patch)
treec4857b85c266149a6f6f61ec01bdb76ba9e4a34a
parentd180fb24e4039659e5f731bbbf80a827aefe517f (diff)
event-manager: become an approver for auth channels
Signed-off-by: Jonny Lamb <jonnylamb@gnome.org>
-rw-r--r--src/empathy-event-manager.c90
-rw-r--r--src/empathy-event-manager.h1
2 files changed, 85 insertions, 6 deletions
diff --git a/src/empathy-event-manager.c b/src/empathy-event-manager.c
index 2f947478b..9ab20b769 100644
--- a/src/empathy-event-manager.c
+++ b/src/empathy-event-manager.c
@@ -76,6 +76,7 @@ typedef struct {
typedef struct {
TpBaseClient *approver;
+ TpBaseClient *auth_approver;
EmpathyContactManager *contact_manager;
GSList *events;
/* Ongoing approvals */
@@ -428,11 +429,46 @@ out:
}
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);
}
diff --git a/src/empathy-event-manager.h b/src/empathy-event-manager.h
index d2d1597e1..16d97c6df 100644
--- a/src/empathy-event-manager.h
+++ b/src/empathy-event-manager.h
@@ -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 {