]> git.0d.be Git - empathy.git/blob - libempathy/empathy-keyring.c
Merge remote-tracking branch 'glassrose/add-All-service-selection-in-debug-window'
[empathy.git] / libempathy / empathy-keyring.c
1 /*
2  * Copyright (C) 2010 Collabora Ltd.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18
19 #include "config.h"
20
21 #include "empathy-keyring.h"
22
23 #include <string.h>
24
25 #include <gnome-keyring.h>
26
27 #include "empathy-utils.h"
28
29 #define DEBUG_FLAG EMPATHY_DEBUG_OTHER
30 #include "empathy-debug.h"
31
32 static GnomeKeyringPasswordSchema account_keyring_schema =
33   { GNOME_KEYRING_ITEM_GENERIC_SECRET,
34     { { "account-id", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
35       { "param-name", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
36       { NULL } } };
37
38 static GnomeKeyringPasswordSchema room_keyring_schema =
39   { GNOME_KEYRING_ITEM_GENERIC_SECRET,
40     { { "account-id", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
41       { "room-id", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
42       { NULL } } };
43
44 gboolean
45 empathy_keyring_is_available (void)
46 {
47   return gnome_keyring_is_available ();
48 }
49
50 /* get */
51
52 static void
53 find_items_cb (GnomeKeyringResult result,
54     GList *list,
55     gpointer user_data)
56 {
57   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
58   GnomeKeyringFound *found;
59
60   if (result != GNOME_KEYRING_RESULT_OK)
61     {
62       GError *error = g_error_new_literal (TP_ERROR,
63           TP_ERROR_DOES_NOT_EXIST,
64           gnome_keyring_result_to_message (result));
65       g_simple_async_result_set_from_error (simple, error);
66       g_clear_error (&error);
67       goto out;
68     }
69
70   if (list == NULL)
71     {
72       g_simple_async_result_set_error (simple, TP_ERROR,
73           TP_ERROR_DOES_NOT_EXIST, "Password not found");
74       goto out;
75     }
76
77   /* Get the first password returned. Ideally we should use the latest
78    * modified or something but we don't have this information from
79    * gnome-keyring atm. */
80   found = list->data;
81   DEBUG ("Got %d secrets; use the first one", g_list_length (list));
82
83   g_simple_async_result_set_op_res_gpointer (simple, g_strdup (found->secret),
84       g_free);
85
86 out:
87   g_simple_async_result_complete (simple);
88   g_object_unref (simple);
89 }
90
91 void
92 empathy_keyring_get_account_password_async (TpAccount *account,
93     GAsyncReadyCallback callback,
94     gpointer user_data)
95 {
96   GSimpleAsyncResult *simple;
97   GnomeKeyringAttributeList *match;
98   const gchar *account_id;
99
100   g_return_if_fail (TP_IS_ACCOUNT (account));
101   g_return_if_fail (callback != NULL);
102
103   simple = g_simple_async_result_new (G_OBJECT (account), callback,
104       user_data, empathy_keyring_get_account_password_async);
105
106   account_id = tp_proxy_get_object_path (account) +
107     strlen (TP_ACCOUNT_OBJECT_PATH_BASE);
108
109   DEBUG ("Trying to get password for: %s", account_id);
110
111   match = gnome_keyring_attribute_list_new ();
112   gnome_keyring_attribute_list_append_string (match, "account-id",
113       account_id);
114   gnome_keyring_attribute_list_append_string (match, "param-name", "password");
115
116   gnome_keyring_find_items (GNOME_KEYRING_ITEM_GENERIC_SECRET,
117       match, find_items_cb, simple, NULL);
118
119   gnome_keyring_attribute_list_free (match);
120 }
121
122 void
123 empathy_keyring_get_room_password_async (TpAccount *account,
124     const gchar *id,
125     GAsyncReadyCallback callback,
126     gpointer user_data)
127 {
128   GSimpleAsyncResult *simple;
129   GnomeKeyringAttributeList *match;
130   const gchar *account_id;
131
132   g_return_if_fail (TP_IS_ACCOUNT (account));
133   g_return_if_fail (id != NULL);
134   g_return_if_fail (callback != NULL);
135
136   simple = g_simple_async_result_new (G_OBJECT (account), callback,
137       user_data, empathy_keyring_get_room_password_async);
138
139   account_id = tp_proxy_get_object_path (account) +
140     strlen (TP_ACCOUNT_OBJECT_PATH_BASE);
141
142   DEBUG ("Trying to get password for room '%s' on account '%s'",
143       id, account_id);
144
145   match = gnome_keyring_attribute_list_new ();
146   gnome_keyring_attribute_list_append_string (match, "account-id",
147       account_id);
148   gnome_keyring_attribute_list_append_string (match, "room-id", id);
149
150   gnome_keyring_find_items (GNOME_KEYRING_ITEM_GENERIC_SECRET,
151       match, find_items_cb, simple, NULL);
152
153   gnome_keyring_attribute_list_free (match);
154 }
155
156 const gchar *
157 empathy_keyring_get_account_password_finish (TpAccount *account,
158     GAsyncResult *result,
159     GError **error)
160 {
161   empathy_implement_finish_return_pointer (account,
162       empathy_keyring_get_account_password_async);
163 }
164
165 const gchar *
166 empathy_keyring_get_room_password_finish (TpAccount *account,
167     GAsyncResult *result,
168     GError **error)
169 {
170   empathy_implement_finish_return_pointer (account,
171       empathy_keyring_get_room_password_async);
172 }
173
174 /* set */
175
176 static void
177 store_password_cb (GnomeKeyringResult result,
178     gpointer user_data)
179 {
180   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
181
182   if (result != GNOME_KEYRING_RESULT_OK)
183     {
184       GError *error = g_error_new_literal (TP_ERROR,
185           TP_ERROR_DOES_NOT_EXIST,
186           gnome_keyring_result_to_message (result));
187       g_simple_async_result_set_from_error (simple, error);
188       g_clear_error (&error);
189     }
190
191   g_simple_async_result_complete (simple);
192   g_object_unref (simple);
193 }
194
195 void
196 empathy_keyring_set_account_password_async (TpAccount *account,
197     const gchar *password,
198     GAsyncReadyCallback callback,
199     gpointer user_data)
200 {
201   GSimpleAsyncResult *simple;
202   const gchar *account_id;
203   gchar *name;
204
205   g_return_if_fail (TP_IS_ACCOUNT (account));
206   g_return_if_fail (password != NULL);
207
208   simple = g_simple_async_result_new (G_OBJECT (account), callback,
209       user_data, empathy_keyring_set_account_password_async);
210
211   account_id = tp_proxy_get_object_path (account) +
212     strlen (TP_ACCOUNT_OBJECT_PATH_BASE);
213
214   DEBUG ("Remembering password for %s", account_id);
215
216   name = g_strdup_printf ("IM account password for %s (%s)",
217       tp_account_get_display_name (account), account_id);
218
219   gnome_keyring_store_password (&account_keyring_schema, NULL, name, password,
220       store_password_cb, simple, NULL,
221       "account-id", account_id,
222       "param-name", "password",
223       NULL);
224
225   g_free (name);
226 }
227
228 void
229 empathy_keyring_set_room_password_async (TpAccount *account,
230     const gchar *id,
231     const gchar *password,
232     GAsyncReadyCallback callback,
233     gpointer user_data)
234 {
235   GSimpleAsyncResult *simple;
236   const gchar *account_id;
237   gchar *name;
238
239   g_return_if_fail (TP_IS_ACCOUNT (account));
240   g_return_if_fail (id != NULL);
241   g_return_if_fail (password != NULL);
242
243   simple = g_simple_async_result_new (G_OBJECT (account), callback,
244       user_data, empathy_keyring_set_room_password_async);
245
246   account_id = tp_proxy_get_object_path (account) +
247     strlen (TP_ACCOUNT_OBJECT_PATH_BASE);
248
249   DEBUG ("Remembering password for room '%s' on account '%s'", id, account_id);
250
251   name = g_strdup_printf ("Password for chatroom '%s' on account %s (%s)",
252       id, tp_account_get_display_name (account), account_id);
253
254   gnome_keyring_store_password (&room_keyring_schema, NULL, name, password,
255       store_password_cb, simple, NULL,
256       "account-id", account_id,
257       "room-id", id,
258       NULL);
259
260   g_free (name);
261 }
262
263 gboolean
264 empathy_keyring_set_account_password_finish (TpAccount *account,
265     GAsyncResult *result,
266     GError **error)
267 {
268   empathy_implement_finish_void (account, empathy_keyring_set_account_password_async);
269 }
270
271 gboolean
272 empathy_keyring_set_room_password_finish (TpAccount *account,
273     GAsyncResult *result,
274     GError **error)
275 {
276   empathy_implement_finish_void (account, empathy_keyring_set_room_password_async);
277 }
278
279 /* delete */
280
281 static void
282 item_delete_cb (GnomeKeyringResult result,
283     gpointer user_data)
284 {
285   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
286
287   if (result != GNOME_KEYRING_RESULT_OK)
288     {
289       GError *error = g_error_new_literal (TP_ERROR,
290           TP_ERROR_DOES_NOT_EXIST,
291           gnome_keyring_result_to_message (result));
292       g_simple_async_result_set_from_error (simple, error);
293       g_clear_error (&error);
294     }
295
296   g_simple_async_result_complete (simple);
297   g_object_unref (simple);
298 }
299
300 static void
301 find_item_to_delete_cb (GnomeKeyringResult result,
302     GList *list,
303     gpointer user_data)
304 {
305   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
306   GnomeKeyringFound *found;
307
308   if (result != GNOME_KEYRING_RESULT_OK || g_list_length (list) != 1)
309     {
310       GError *error = g_error_new_literal (TP_ERROR,
311           TP_ERROR_DOES_NOT_EXIST,
312           gnome_keyring_result_to_message (result));
313       g_simple_async_result_set_from_error (simple, error);
314       g_clear_error (&error);
315
316       g_simple_async_result_complete (simple);
317       g_object_unref (simple);
318       return;
319     }
320
321   found = list->data;
322
323   gnome_keyring_item_delete (NULL, found->item_id, item_delete_cb,
324       simple, NULL);
325 }
326
327 void
328 empathy_keyring_delete_account_password_async (TpAccount *account,
329     GAsyncReadyCallback callback,
330     gpointer user_data)
331 {
332   GSimpleAsyncResult *simple;
333   GnomeKeyringAttributeList *match;
334   const gchar *account_id;
335
336   g_return_if_fail (TP_IS_ACCOUNT (account));
337
338   simple = g_simple_async_result_new (G_OBJECT (account), callback,
339       user_data, empathy_keyring_delete_account_password_async);
340
341   account_id = tp_proxy_get_object_path (account) +
342     strlen (TP_ACCOUNT_OBJECT_PATH_BASE);
343
344   match = gnome_keyring_attribute_list_new ();
345   gnome_keyring_attribute_list_append_string (match, "account-id",
346       account_id);
347   gnome_keyring_attribute_list_append_string (match, "param-name", "password");
348
349   gnome_keyring_find_items (GNOME_KEYRING_ITEM_GENERIC_SECRET,
350       match, find_item_to_delete_cb, simple, NULL);
351
352   gnome_keyring_attribute_list_free (match);
353 }
354
355 gboolean
356 empathy_keyring_delete_account_password_finish (TpAccount *account,
357     GAsyncResult *result,
358     GError **error)
359 {
360   empathy_implement_finish_void (account, empathy_keyring_delete_account_password_async);
361 }
362