]> git.0d.be Git - empathy.git/blob - libempathy/empathy-auth-factory.c
Add empathy_contact_dup_best_for_action()
[empathy.git] / libempathy / empathy-auth-factory.c
1 /*
2  * empathy-auth-factory.c - Source for EmpathyAuthFactory
3  * Copyright (C) 2010 Collabora Ltd.
4  * @author Cosimo Cecchi <cosimo.cecchi@collabora.co.uk>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  */
20
21 #include "empathy-auth-factory.h"
22
23 #include <telepathy-glib/interfaces.h>
24 #include <telepathy-glib/simple-handler.h>
25 #include <telepathy-glib/util.h>
26
27 #define DEBUG_FLAG EMPATHY_DEBUG_TLS
28 #include "empathy-debug.h"
29 #include "empathy-server-tls-handler.h"
30 #include "empathy-utils.h"
31
32 #include "extensions/extensions.h"
33
34 G_DEFINE_TYPE (EmpathyAuthFactory, empathy_auth_factory, G_TYPE_OBJECT);
35
36 typedef struct {
37   TpBaseClient *handler;
38   TpHandleChannelsContext *context;
39
40   gboolean dispose_run;
41 } EmpathyAuthFactoryPriv;
42
43 enum {
44   NEW_SERVER_TLS_HANDLER,
45   LAST_SIGNAL,
46 };
47
48 static guint signals[LAST_SIGNAL] = { 0, };
49
50 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyAuthFactory)
51
52 static EmpathyAuthFactory *auth_factory_singleton = NULL;
53
54 static void
55 server_tls_handler_ready_cb (GObject *source,
56     GAsyncResult *res,
57     gpointer user_data)
58 {
59   EmpathyServerTLSHandler *handler;
60   GError *error = NULL;
61   EmpathyAuthFactory *self = user_data;
62   EmpathyAuthFactoryPriv *priv = GET_PRIV (self);
63
64   handler = empathy_server_tls_handler_new_finish (res, &error);
65
66   if (error != NULL)
67     {
68       DEBUG ("Failed to create a server TLS handler; error %s",
69           error->message);
70       tp_handle_channels_context_fail (priv->context, error);
71
72       g_error_free (error);
73     }
74   else
75     {
76       tp_handle_channels_context_accept (priv->context);
77       g_signal_emit (self, signals[NEW_SERVER_TLS_HANDLER], 0,
78           handler);
79
80       g_object_unref (handler);
81     }
82
83   tp_clear_object (&priv->context);
84 }
85
86 static void
87 handle_channels_cb (TpSimpleHandler *handler,
88     TpAccount *account,
89     TpConnection *connection,
90     GList *channels,
91     GList *requests_satisfied,
92     gint64 user_action_time,
93     TpHandleChannelsContext *context,
94     gpointer user_data)
95 {
96   TpChannel *channel;
97   const GError *dbus_error;
98   GError *error = NULL;
99   EmpathyAuthFactory *self = user_data;
100   EmpathyAuthFactoryPriv *priv = GET_PRIV (self);
101
102   DEBUG ("Handle TLS carrier channels.");
103
104   /* there can't be more than one ServerTLSConnection channels
105    * at the same time, for the same connection/account.
106    */
107   if (g_list_length (channels) != 1)
108     {
109       g_set_error_literal (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
110           "Can't handle more than one ServerTLSConnection channel "
111           "for the same connection.");
112
113       goto error;
114     }
115
116   channel = channels->data;
117
118   if (tp_channel_get_channel_type_id (channel) !=
119       EMP_IFACE_QUARK_CHANNEL_TYPE_SERVER_TLS_CONNECTION)
120     {
121       g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
122           "Can only handle ServerTLSConnection channels, this was a %s "
123           "channel", tp_channel_get_channel_type (channel));
124
125       goto error;
126     }
127
128   dbus_error = tp_proxy_get_invalidated (channel);
129
130   if (dbus_error != NULL)
131     {
132       error = g_error_copy (dbus_error);
133       goto error;
134     }
135
136   /* create a handler */
137   priv->context = g_object_ref (context);
138   tp_handle_channels_context_delay (context);
139   empathy_server_tls_handler_new_async (channel, server_tls_handler_ready_cb,
140       self);
141
142   return;
143
144  error:
145   tp_handle_channels_context_fail (context, error);
146   g_clear_error (&error);
147 }
148
149 static GObject *
150 empathy_auth_factory_constructor (GType type,
151     guint n_params,
152     GObjectConstructParam *params)
153 {
154   GObject *retval;
155
156   if (auth_factory_singleton != NULL)
157     {
158       retval = g_object_ref (auth_factory_singleton);
159     }
160   else
161     {
162       retval = G_OBJECT_CLASS (empathy_auth_factory_parent_class)->constructor
163         (type, n_params, params);
164
165       auth_factory_singleton = EMPATHY_AUTH_FACTORY (retval);
166       g_object_add_weak_pointer (retval, (gpointer *) &auth_factory_singleton);
167     }
168
169   return retval;
170 }
171
172 static void
173 empathy_auth_factory_init (EmpathyAuthFactory *self)
174 {
175   EmpathyAuthFactoryPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
176       EMPATHY_TYPE_AUTH_FACTORY, EmpathyAuthFactoryPriv);
177   TpDBusDaemon *bus;
178   GError *error = NULL;
179
180   self->priv = priv;
181
182   bus = tp_dbus_daemon_dup (&error);
183   if (error != NULL)
184     {
185       g_critical ("Failed to get TpDBusDaemon: %s", error->message);
186       g_error_free (error);
187       return;
188     }
189
190   priv->handler = tp_simple_handler_new (bus, FALSE, FALSE, "Empathy.Auth",
191       FALSE, handle_channels_cb, self, NULL);
192
193   tp_base_client_take_handler_filter (priv->handler, tp_asv_new (
194           TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING,
195           EMP_IFACE_CHANNEL_TYPE_SERVER_TLS_CONNECTION,
196           TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT,
197           TP_HANDLE_TYPE_NONE, NULL));
198
199   g_object_unref (bus);
200 }
201
202 static void
203 empathy_auth_factory_dispose (GObject *object)
204 {
205   EmpathyAuthFactoryPriv *priv = GET_PRIV (object);
206
207   if (priv->dispose_run)
208     return;
209
210   priv->dispose_run = TRUE;
211
212   tp_clear_object (&priv->handler);
213   tp_clear_object (&priv->context);
214
215   G_OBJECT_CLASS (empathy_auth_factory_parent_class)->dispose (object);
216 }
217
218 static void
219 empathy_auth_factory_class_init (EmpathyAuthFactoryClass *klass)
220 {
221   GObjectClass *oclass = G_OBJECT_CLASS (klass);
222
223   oclass->constructor = empathy_auth_factory_constructor;
224   oclass->dispose = empathy_auth_factory_dispose;
225
226   g_type_class_add_private (klass, sizeof (EmpathyAuthFactoryPriv));
227
228   signals[NEW_SERVER_TLS_HANDLER] =
229     g_signal_new ("new-server-tls-handler",
230       G_TYPE_FROM_CLASS (klass),
231       G_SIGNAL_RUN_LAST, 0,
232       NULL, NULL,
233       g_cclosure_marshal_VOID__OBJECT,
234       G_TYPE_NONE,
235       1, EMPATHY_TYPE_SERVER_TLS_HANDLER);
236 }
237
238 EmpathyAuthFactory *
239 empathy_auth_factory_dup_singleton (void)
240 {
241   return g_object_new (EMPATHY_TYPE_AUTH_FACTORY, NULL);
242 }
243
244 gboolean
245 empathy_auth_factory_register (EmpathyAuthFactory *self,
246     GError **error)
247 {
248   EmpathyAuthFactoryPriv *priv = GET_PRIV (self);
249
250   return tp_base_client_register (priv->handler, error);
251 }