]> git.0d.be Git - empathy.git/blob - libempathy/empathy-keyring.c
find_items_cb: always use the first password found
[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 secret");
82
83   g_simple_async_result_set_op_res_gpointer (simple, found->secret, NULL);
84
85 out:
86   g_simple_async_result_complete (simple);
87   g_object_unref (simple);
88 }
89
90 void
91 empathy_keyring_get_account_password_async (TpAccount *account,
92     GAsyncReadyCallback callback,
93     gpointer user_data)
94 {
95   GSimpleAsyncResult *simple;
96   GnomeKeyringAttributeList *match;
97   const gchar *account_id;
98
99   g_return_if_fail (TP_IS_ACCOUNT (account));
100   g_return_if_fail (callback != NULL);
101
102   simple = g_simple_async_result_new (G_OBJECT (account), callback,
103       user_data, empathy_keyring_get_account_password_async);
104
105   account_id = tp_proxy_get_object_path (account) +
106     strlen (TP_ACCOUNT_OBJECT_PATH_BASE);
107
108   DEBUG ("Trying to get password for: %s", account_id);
109
110   match = gnome_keyring_attribute_list_new ();
111   gnome_keyring_attribute_list_append_string (match, "account-id",
112       account_id);
113   gnome_keyring_attribute_list_append_string (match, "param-name", "password");
114
115   gnome_keyring_find_items (GNOME_KEYRING_ITEM_GENERIC_SECRET,
116       match, find_items_cb, simple, NULL);
117
118   gnome_keyring_attribute_list_free (match);
119 }
120
121 void
122 empathy_keyring_get_room_password_async (TpAccount *account,
123     const gchar *id,
124     GAsyncReadyCallback callback,
125     gpointer user_data)
126 {
127   GSimpleAsyncResult *simple;
128   GnomeKeyringAttributeList *match;
129   const gchar *account_id;
130
131   g_return_if_fail (TP_IS_ACCOUNT (account));
132   g_return_if_fail (id != NULL);
133   g_return_if_fail (callback != NULL);
134
135   simple = g_simple_async_result_new (G_OBJECT (account), callback,
136       user_data, empathy_keyring_get_room_password_async);
137
138   account_id = tp_proxy_get_object_path (account) +
139     strlen (TP_ACCOUNT_OBJECT_PATH_BASE);
140
141   DEBUG ("Trying to get password for room '%s' on account '%s'",
142       id, account_id);
143
144   match = gnome_keyring_attribute_list_new ();
145   gnome_keyring_attribute_list_append_string (match, "account-id",
146       account_id);
147   gnome_keyring_attribute_list_append_string (match, "room-id", id);
148
149   gnome_keyring_find_items (GNOME_KEYRING_ITEM_GENERIC_SECRET,
150       match, find_items_cb, simple, NULL);
151
152   gnome_keyring_attribute_list_free (match);
153 }
154
155 const gchar *
156 empathy_keyring_get_account_password_finish (TpAccount *account,
157     GAsyncResult *result,
158     GError **error)
159 {
160   empathy_implement_finish_return_pointer (account,
161       empathy_keyring_get_account_password_async);
162 }
163
164 const gchar *
165 empathy_keyring_get_room_password_finish (TpAccount *account,
166     GAsyncResult *result,
167     GError **error)
168 {
169   empathy_implement_finish_return_pointer (account,
170       empathy_keyring_get_room_password_async);
171 }
172
173 /* set */
174
175 static void
176 store_password_cb (GnomeKeyringResult result,
177     gpointer user_data)
178 {
179   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
180
181   if (result != GNOME_KEYRING_RESULT_OK)
182     {
183       GError *error = g_error_new_literal (TP_ERROR,
184           TP_ERROR_DOES_NOT_EXIST,
185           gnome_keyring_result_to_message (result));
186       g_simple_async_result_set_from_error (simple, error);
187       g_clear_error (&error);
188     }
189
190   g_simple_async_result_complete (simple);
191   g_object_unref (simple);
192 }
193
194 void
195 empathy_keyring_set_account_password_async (TpAccount *account,
196     const gchar *password,
197     GAsyncReadyCallback callback,
198     gpointer user_data)
199 {
200   GSimpleAsyncResult *simple;
201   const gchar *account_id;
202   gchar *name;
203
204   g_return_if_fail (TP_IS_ACCOUNT (account));
205   g_return_if_fail (password != NULL);
206
207   simple = g_simple_async_result_new (G_OBJECT (account), callback,
208       user_data, empathy_keyring_set_account_password_async);
209
210   account_id = tp_proxy_get_object_path (account) +
211     strlen (TP_ACCOUNT_OBJECT_PATH_BASE);
212
213   DEBUG ("Remembering password for %s", account_id);
214
215   name = g_strdup_printf ("IM account password for %s (%s)",
216       tp_account_get_display_name (account), account_id);
217
218   gnome_keyring_store_password (&account_keyring_schema, NULL, name, password,
219       store_password_cb, simple, NULL,
220       "account-id", account_id,
221       "param-name", "password",
222       NULL);
223
224   g_free (name);
225 }
226
227 void
228 empathy_keyring_set_room_password_async (TpAccount *account,
229     const gchar *id,
230     const gchar *password,
231     GAsyncReadyCallback callback,
232     gpointer user_data)
233 {
234   GSimpleAsyncResult *simple;
235   const gchar *account_id;
236   gchar *name;
237
238   g_return_if_fail (TP_IS_ACCOUNT (account));
239   g_return_if_fail (id != NULL);
240   g_return_if_fail (password != NULL);
241
242   simple = g_simple_async_result_new (G_OBJECT (account), callback,
243       user_data, empathy_keyring_set_room_password_async);
244
245   account_id = tp_proxy_get_object_path (account) +
246     strlen (TP_ACCOUNT_OBJECT_PATH_BASE);
247
248   DEBUG ("Remembering password for room '%s' on account '%s'", id, account_id);
249
250   name = g_strdup_printf ("Password for chatroom '%s' on account %s (%s)",
251       id, tp_account_get_display_name (account), account_id);
252
253   gnome_keyring_store_password (&room_keyring_schema, NULL, name, password,
254       store_password_cb, simple, NULL,
255       "account-id", account_id,
256       "room-id", id,
257       NULL);
258
259   g_free (name);
260 }
261
262 gboolean
263 empathy_keyring_set_account_password_finish (TpAccount *account,
264     GAsyncResult *result,
265     GError **error)
266 {
267   empathy_implement_finish_void (account, empathy_keyring_set_account_password_async);
268 }
269
270 gboolean
271 empathy_keyring_set_room_password_finish (TpAccount *account,
272     GAsyncResult *result,
273     GError **error)
274 {
275   empathy_implement_finish_void (account, empathy_keyring_set_room_password_async);
276 }
277
278 /* delete */
279
280 static void
281 item_delete_cb (GnomeKeyringResult result,
282     gpointer user_data)
283 {
284   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
285
286   if (result != GNOME_KEYRING_RESULT_OK)
287     {
288       GError *error = g_error_new_literal (TP_ERROR,
289           TP_ERROR_DOES_NOT_EXIST,
290           gnome_keyring_result_to_message (result));
291       g_simple_async_result_set_from_error (simple, error);
292       g_clear_error (&error);
293     }
294
295   g_simple_async_result_complete (simple);
296   g_object_unref (simple);
297 }
298
299 static void
300 find_item_to_delete_cb (GnomeKeyringResult result,
301     GList *list,
302     gpointer user_data)
303 {
304   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
305   GnomeKeyringFound *found;
306
307   if (result != GNOME_KEYRING_RESULT_OK || g_list_length (list) != 1)
308     {
309       GError *error = g_error_new_literal (TP_ERROR,
310           TP_ERROR_DOES_NOT_EXIST,
311           gnome_keyring_result_to_message (result));
312       g_simple_async_result_set_from_error (simple, error);
313       g_clear_error (&error);
314
315       g_simple_async_result_complete (simple);
316       g_object_unref (simple);
317       return;
318     }
319
320   found = list->data;
321
322   gnome_keyring_item_delete (NULL, found->item_id, item_delete_cb,
323       simple, NULL);
324 }
325
326 void
327 empathy_keyring_delete_account_password_async (TpAccount *account,
328     GAsyncReadyCallback callback,
329     gpointer user_data)
330 {
331   GSimpleAsyncResult *simple;
332   GnomeKeyringAttributeList *match;
333   const gchar *account_id;
334
335   g_return_if_fail (TP_IS_ACCOUNT (account));
336
337   simple = g_simple_async_result_new (G_OBJECT (account), callback,
338       user_data, empathy_keyring_delete_account_password_async);
339
340   account_id = tp_proxy_get_object_path (account) +
341     strlen (TP_ACCOUNT_OBJECT_PATH_BASE);
342
343   match = gnome_keyring_attribute_list_new ();
344   gnome_keyring_attribute_list_append_string (match, "account-id",
345       account_id);
346   gnome_keyring_attribute_list_append_string (match, "param-name", "password");
347
348   gnome_keyring_find_items (GNOME_KEYRING_ITEM_GENERIC_SECRET,
349       match, find_item_to_delete_cb, simple, NULL);
350
351   gnome_keyring_attribute_list_free (match);
352 }
353
354 gboolean
355 empathy_keyring_delete_account_password_finish (TpAccount *account,
356     GAsyncResult *result,
357     GError **error)
358 {
359   empathy_implement_finish_void (account, empathy_keyring_delete_account_password_async);
360 }
361