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