1
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
3
* Copyright (C) 2012 Red Hat, Inc.
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Lesser General Public
7
* License as published by the Free Software Foundation; either
8
* version 2 of the License, or (at your option) any later version.
10
* This library is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Lesser General Public License for more details.
15
* You should have received a copy of the GNU Lesser General
16
* Public License along with this library; if not, write to the
17
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18
* Boston, MA 02111-1307, USA.
20
* Authors: Debarshi Ray <debarshir@gnome.org>
21
* Ray Strode <rstrode@redhat.com>
26
#include <glib/gi18n-lib.h>
27
#include <libsecret/secret.h>
29
#include "goaprovider.h"
30
#include "goalogging.h"
33
static const SecretSchema secret_password_schema =
35
"org.gnome.OnlineAccounts", SECRET_SCHEMA_DONT_MATCH_NAME,
37
{ "goa-identity", SECRET_SCHEMA_ATTRIBUTE_STRING },
43
goa_utils_check_duplicate (GoaClient *client,
44
const gchar *identity,
45
const gchar *provider_type,
46
GoaPeekInterfaceFunc func,
55
accounts = goa_client_get_accounts (client);
56
for (l = accounts; l != NULL; l = l->next)
58
GoaObject *object = GOA_OBJECT (l->data);
61
const gchar *identity_from_object;
62
const gchar *provider_type_from_object;
64
account = goa_object_peek_account (object);
65
interface = (*func) (object);
66
if (interface == NULL)
69
provider_type_from_object = goa_account_get_provider_type (account);
70
if (g_strcmp0 (provider_type_from_object, provider_type) != 0)
73
identity_from_object = goa_account_get_identity (account);
74
if (g_strcmp0 (identity_from_object, identity) == 0)
76
const gchar *presentation_identity;
77
const gchar *provider_name;
79
presentation_identity = goa_account_get_presentation_identity (account);
80
provider_name = goa_account_get_provider_name (account);
83
GOA_ERROR_ACCOUNT_EXISTS,
84
_("A %s account already exists for %s"),
86
presentation_identity);
94
g_list_free_full (accounts, g_object_unref);
99
goa_utils_set_dialog_title (GoaProvider *provider, GtkDialog *dialog, gboolean add_account)
101
gchar *provider_name;
104
provider_name = goa_provider_get_provider_name (GOA_PROVIDER (provider), NULL);
105
/* Translators: the %s is the name of the provider. eg., Google. */
106
title = g_strdup_printf (_("%s account"), provider_name);
107
gtk_window_set_title (GTK_WINDOW (dialog), title);
109
g_free (provider_name);
113
goa_utils_delete_credentials_sync (GoaProvider *provider,
115
GCancellable *cancellable,
120
const gchar *identity;
122
g_return_val_if_fail (GOA_IS_PROVIDER (provider), FALSE);
123
g_return_val_if_fail (GOA_IS_ACCOUNT (object), FALSE);
124
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
125
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
131
identity = goa_account_get_id (object);
133
password_key = g_strdup_printf ("%s:gen%d:%s",
134
goa_provider_get_provider_type (GOA_PROVIDER (provider)),
135
goa_provider_get_credentials_generation (GOA_PROVIDER (provider)),
138
if (!secret_password_clear_sync (&secret_password_schema,
141
"goa-identity", password_key,
144
g_set_error_literal (error,
146
GOA_ERROR_FAILED, /* TODO: more specific */
147
_("Failed to delete credentials from the keyring"));
154
g_free (password_key);
159
goa_utils_lookup_credentials_sync (GoaProvider *provider,
161
GCancellable *cancellable,
167
const gchar *identity;
169
g_return_val_if_fail (GOA_IS_PROVIDER (provider), NULL);
170
g_return_val_if_fail (GOA_IS_OBJECT (object) && goa_object_peek_account (object) != NULL, FALSE);
171
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
172
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
178
identity = goa_account_get_id (goa_object_peek_account (object));
180
password_key = g_strdup_printf ("%s:gen%d:%s",
181
goa_provider_get_provider_type (GOA_PROVIDER (provider)),
182
goa_provider_get_credentials_generation (GOA_PROVIDER (provider)),
185
password = secret_password_lookup_sync (&secret_password_schema,
188
"goa-identity", password_key,
190
if (password == NULL)
192
g_set_error_literal (error,
194
GOA_ERROR_FAILED, /* TODO: more specific */
195
_("Failed to retrieve credentials from the keyring"));
199
ret = g_variant_parse (NULL, /* GVariantType */
206
g_prefix_error (error, _("Error parsing result obtained from the keyring: "));
210
if (g_variant_is_floating (ret))
211
g_variant_ref_sink (ret);
215
g_free (password_key);
220
goa_utils_store_credentials_for_id_sync (GoaProvider *provider,
222
GVariant *credentials,
223
GCancellable *cancellable,
227
gchar *credentials_str;
228
gchar *password_description;
231
g_return_val_if_fail (GOA_IS_PROVIDER (provider), FALSE);
232
g_return_val_if_fail (id != NULL && id[0] != '\0', FALSE);
233
g_return_val_if_fail (credentials != NULL, FALSE);
234
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
235
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
239
credentials_str = g_variant_print (credentials, TRUE);
240
g_variant_ref_sink (credentials);
241
g_variant_unref (credentials);
243
password_key = g_strdup_printf ("%s:gen%d:%s",
244
goa_provider_get_provider_type (GOA_PROVIDER (provider)),
245
goa_provider_get_credentials_generation (GOA_PROVIDER (provider)),
247
/* Translators: The %s is the type of the provider, e.g. 'google' or 'facebook' */
248
password_description = g_strdup_printf (_("GOA %s credentials for identity %s"),
249
goa_provider_get_provider_type (GOA_PROVIDER (provider)),
252
if (!secret_password_store_sync (&secret_password_schema,
253
SECRET_COLLECTION_DEFAULT, /* default keyring */
254
password_description,
258
"goa-identity", password_key,
261
g_set_error_literal (error,
263
GOA_ERROR_FAILED, /* TODO: more specific */
264
_("Failed to store credentials in the keyring"));
271
g_free (credentials_str);
272
g_free (password_key);
273
g_free (password_description);
278
goa_utils_store_credentials_for_object_sync (GoaProvider *provider,
280
GVariant *credentials,
281
GCancellable *cancellable,
286
g_return_val_if_fail (GOA_IS_PROVIDER (provider), FALSE);
287
g_return_val_if_fail (GOA_IS_OBJECT (object) && goa_object_peek_account (object) != NULL, FALSE);
288
g_return_val_if_fail (credentials != NULL, FALSE);
289
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
290
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
292
id = goa_account_get_id (goa_object_peek_account (object));
293
return goa_utils_store_credentials_for_id_sync (provider, id, credentials, cancellable, error);
297
goa_utils_keyfile_remove_key (GoaAccount *account, const gchar *key)
308
path = g_strdup_printf ("%s/goa-1.0/accounts.conf", g_get_user_config_dir ());
309
group = g_strdup_printf ("Account %s", goa_account_get_id (account));
311
key_file = g_key_file_new ();
313
if (!g_key_file_load_from_file (key_file,
315
G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS,
318
goa_warning ("Error loading keyfile %s: %s (%s, %d)",
321
g_quark_to_string (error->domain),
323
g_error_free (error);
327
g_key_file_remove_key (key_file, group, key, NULL);
328
contents = g_key_file_to_data (key_file, &length, NULL);
331
if (!g_file_set_contents (path, contents, length, &error))
333
g_prefix_error (&error, "Error writing key-value-file %s: ", path);
334
goa_warning ("%s (%s, %d)", error->message, g_quark_to_string (error->domain), error->code);
335
g_error_free (error);
341
g_key_file_free (key_file);
347
goa_utils_keyfile_set_boolean (GoaAccount *account, const gchar *key, gboolean value)
358
path = g_strdup_printf ("%s/goa-1.0/accounts.conf", g_get_user_config_dir ());
359
group = g_strdup_printf ("Account %s", goa_account_get_id (account));
361
key_file = g_key_file_new ();
363
if (!g_key_file_load_from_file (key_file,
365
G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS,
368
goa_warning ("Error loading keyfile %s: %s (%s, %d)",
371
g_quark_to_string (error->domain),
373
g_error_free (error);
377
g_key_file_set_boolean (key_file, group, key, value);
378
contents = g_key_file_to_data (key_file, &length, NULL);
381
if (!g_file_set_contents (path, contents, length, &error))
383
g_prefix_error (&error, "Error writing key-value-file %s: ", path);
384
goa_warning ("%s (%s, %d)", error->message, g_quark_to_string (error->domain), error->code);
385
g_error_free (error);
391
g_key_file_free (key_file);
397
goa_utils_keyfile_set_string (GoaAccount *account, const gchar *key, const gchar *value)
408
path = g_strdup_printf ("%s/goa-1.0/accounts.conf", g_get_user_config_dir ());
409
group = g_strdup_printf ("Account %s", goa_account_get_id (account));
411
key_file = g_key_file_new ();
413
if (!g_key_file_load_from_file (key_file,
415
G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS,
418
goa_warning ("Error loading keyfile %s: %s (%s, %d)",
421
g_quark_to_string (error->domain),
423
g_error_free (error);
427
g_key_file_set_string (key_file, group, key, value);
428
contents = g_key_file_to_data (key_file, &length, NULL);
431
if (!g_file_set_contents (path, contents, length, &error))
433
g_prefix_error (&error, "Error writing key-value-file %s: ", path);
434
goa_warning ("%s (%s, %d)", error->message, g_quark_to_string (error->domain), error->code);
435
g_error_free (error);
441
g_key_file_free (key_file);