]> git.0d.be Git - empathy.git/blob - libempathy/empathy-keyring.c
UOA auth handler: Inform SSO when access token didn't work
[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 <libsecret/secret.h>
28
29 #include "empathy-utils.h"
30
31 #define DEBUG_FLAG EMPATHY_DEBUG_OTHER
32 #include "empathy-debug.h"
33
34 static const SecretSchema account_keyring_schema =
35   { "org.gnome.Empathy.Account", SECRET_SCHEMA_DONT_MATCH_NAME,
36     { { "account-id", SECRET_SCHEMA_ATTRIBUTE_STRING },
37       { "param-name", SECRET_SCHEMA_ATTRIBUTE_STRING },
38       { NULL } } };
39
40 static const SecretSchema room_keyring_schema =
41   { "org.gnome.Empathy.Room", SECRET_SCHEMA_DONT_MATCH_NAME,
42     { { "account-id", SECRET_SCHEMA_ATTRIBUTE_STRING },
43       { "room-id", SECRET_SCHEMA_ATTRIBUTE_STRING },
44       { NULL } } };
45
46 gboolean
47 empathy_keyring_is_available (void)
48 {
49   return TRUE;
50 }
51
52 /* get */
53
54 static void
55 lookup_item_cb (GObject *source,
56     GAsyncResult *result,
57     gpointer user_data)
58 {
59   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
60   GError *error = NULL;
61   gchar *password;
62
63   password = secret_password_lookup_finish (result, &error);
64   if (error != NULL)
65     {
66       g_simple_async_result_set_error (simple, TP_ERROR,
67           TP_ERROR_DOES_NOT_EXIST, "%s", error->message);
68       g_clear_error (&error);
69       goto out;
70     }
71
72   if (password == 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   g_simple_async_result_set_op_res_gpointer (simple, password,
80       (GDestroyNotify) secret_password_free);
81
82 out:
83   g_simple_async_result_complete (simple);
84   g_object_unref (simple);
85 }
86
87 void
88 empathy_keyring_get_account_password_async (TpAccount *account,
89     GAsyncReadyCallback callback,
90     gpointer user_data)
91 {
92   GSimpleAsyncResult *simple;
93   const gchar *account_id;
94
95   g_return_if_fail (TP_IS_ACCOUNT (account));
96   g_return_if_fail (callback != NULL);
97
98   simple = g_simple_async_result_new (G_OBJECT (account), callback,
99       user_data, empathy_keyring_get_account_password_async);
100
101   account_id = tp_proxy_get_object_path (account) +
102     strlen (TP_ACCOUNT_OBJECT_PATH_BASE);
103
104   DEBUG ("Trying to get password for: %s", account_id);
105
106   secret_password_lookup (&account_keyring_schema, NULL,
107           lookup_item_cb, simple,
108           "account-id", account_id,
109           "param-name", "password",
110           NULL);
111 }
112
113 void
114 empathy_keyring_get_room_password_async (TpAccount *account,
115     const gchar *id,
116     GAsyncReadyCallback callback,
117     gpointer user_data)
118 {
119   GSimpleAsyncResult *simple;
120   const gchar *account_id;
121
122   g_return_if_fail (TP_IS_ACCOUNT (account));
123   g_return_if_fail (id != NULL);
124   g_return_if_fail (callback != NULL);
125
126   simple = g_simple_async_result_new (G_OBJECT (account), callback,
127       user_data, empathy_keyring_get_room_password_async);
128
129   account_id = tp_proxy_get_object_path (account) +
130     strlen (TP_ACCOUNT_OBJECT_PATH_BASE);
131
132   DEBUG ("Trying to get password for room '%s' on account '%s'",
133       id, account_id);
134
135   secret_password_lookup (&room_keyring_schema, NULL,
136           lookup_item_cb, simple,
137           "account-id", account_id,
138           "room-id", id,
139           NULL);
140 }
141
142 const gchar *
143 empathy_keyring_get_account_password_finish (TpAccount *account,
144     GAsyncResult *result,
145     GError **error)
146 {
147   empathy_implement_finish_return_pointer (account,
148       empathy_keyring_get_account_password_async);
149 }
150
151 const gchar *
152 empathy_keyring_get_room_password_finish (TpAccount *account,
153     GAsyncResult *result,
154     GError **error)
155 {
156   empathy_implement_finish_return_pointer (account,
157       empathy_keyring_get_room_password_async);
158 }
159
160 /* set */
161
162 static void
163 store_password_cb (GObject *source,
164     GAsyncResult *result,
165     gpointer user_data)
166 {
167   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
168   GError *error = NULL;
169
170   if (!secret_password_store_finish (result, &error))
171     {
172       g_simple_async_result_set_error (simple, TP_ERROR,
173           TP_ERROR_DOES_NOT_EXIST, "%s", error->message);
174       g_error_free (error);
175     }
176
177   g_simple_async_result_complete (simple);
178   g_object_unref (simple);
179 }
180
181 void
182 empathy_keyring_set_account_password_async (TpAccount *account,
183     const gchar *password,
184     GAsyncReadyCallback callback,
185     gpointer user_data)
186 {
187   GSimpleAsyncResult *simple;
188   const gchar *account_id;
189   gchar *name;
190
191   g_return_if_fail (TP_IS_ACCOUNT (account));
192   g_return_if_fail (password != NULL);
193
194   simple = g_simple_async_result_new (G_OBJECT (account), callback,
195       user_data, empathy_keyring_set_account_password_async);
196
197   account_id = tp_proxy_get_object_path (account) +
198     strlen (TP_ACCOUNT_OBJECT_PATH_BASE);
199
200   DEBUG ("Remembering password for %s", account_id);
201
202   name = g_strdup_printf (_("IM account password for %s (%s)"),
203       tp_account_get_display_name (account), account_id);
204
205   secret_password_store (&account_keyring_schema, NULL, name, password,
206       NULL, store_password_cb, simple,
207       "account-id", account_id,
208       "param-name", "password",
209       NULL);
210
211   g_free (name);
212 }
213
214 void
215 empathy_keyring_set_room_password_async (TpAccount *account,
216     const gchar *id,
217     const gchar *password,
218     GAsyncReadyCallback callback,
219     gpointer user_data)
220 {
221   GSimpleAsyncResult *simple;
222   const gchar *account_id;
223   gchar *name;
224
225   g_return_if_fail (TP_IS_ACCOUNT (account));
226   g_return_if_fail (id != NULL);
227   g_return_if_fail (password != NULL);
228
229   simple = g_simple_async_result_new (G_OBJECT (account), callback,
230       user_data, empathy_keyring_set_room_password_async);
231
232   account_id = tp_proxy_get_object_path (account) +
233     strlen (TP_ACCOUNT_OBJECT_PATH_BASE);
234
235   DEBUG ("Remembering password for room '%s' on account '%s'", id, account_id);
236
237   name = g_strdup_printf (_("Password for chatroom '%s' on account %s (%s)"),
238       id, tp_account_get_display_name (account), account_id);
239
240   secret_password_store (&room_keyring_schema, NULL, name, password,
241       NULL, store_password_cb, simple,
242       "account-id", account_id,
243       "room-id", id,
244       NULL);
245
246   g_free (name);
247 }
248
249 gboolean
250 empathy_keyring_set_account_password_finish (TpAccount *account,
251     GAsyncResult *result,
252     GError **error)
253 {
254   empathy_implement_finish_void (account, empathy_keyring_set_account_password_async);
255 }
256
257 gboolean
258 empathy_keyring_set_room_password_finish (TpAccount *account,
259     GAsyncResult *result,
260     GError **error)
261 {
262   empathy_implement_finish_void (account, empathy_keyring_set_room_password_async);
263 }
264
265 /* delete */
266
267 static void
268 items_delete_cb (GObject *source,
269     GAsyncResult *result,
270     gpointer user_data)
271 {
272   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
273   GError *error = NULL;
274
275   if (!secret_password_clear_finish (result, &error))
276     {
277       g_simple_async_result_set_error (simple, TP_ERROR,
278               TP_ERROR_DOES_NOT_EXIST, "%s", error->message);
279       g_error_free (error);
280     }
281
282   g_simple_async_result_complete (simple);
283   g_object_unref (simple);
284 }
285
286 void
287 empathy_keyring_delete_account_password_async (TpAccount *account,
288     GAsyncReadyCallback callback,
289     gpointer user_data)
290 {
291   GSimpleAsyncResult *simple;
292   const gchar *account_id;
293
294   g_return_if_fail (TP_IS_ACCOUNT (account));
295
296   simple = g_simple_async_result_new (G_OBJECT (account), callback,
297       user_data, empathy_keyring_delete_account_password_async);
298
299   account_id = tp_proxy_get_object_path (account) +
300     strlen (TP_ACCOUNT_OBJECT_PATH_BASE);
301
302   secret_password_clear (&account_keyring_schema, NULL,
303           items_delete_cb, simple,
304           "account-id", account_id,
305           "param-name", "password",
306           NULL);
307 }
308
309 gboolean
310 empathy_keyring_delete_account_password_finish (TpAccount *account,
311     GAsyncResult *result,
312     GError **error)
313 {
314   empathy_implement_finish_void (account, empathy_keyring_delete_account_password_async);
315 }