Branch data Line data Source code
1 : : /* vi: set et sw=4 ts=4 cino=t0,(0: */
2 : : /*
3 : : * This file is part of libaccounts-qt
4 : : *
5 : : * Copyright (C) 2009-2011 Nokia Corporation.
6 : : * Copyright (C) 2012 Canonical Ltd.
7 : : *
8 : : * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
9 : : *
10 : : * This library is free software; you can redistribute it and/or
11 : : * modify it under the terms of the GNU Lesser General Public License
12 : : * version 2.1 as published by the Free Software Foundation.
13 : : *
14 : : * This library is distributed in the hope that it will be useful, but
15 : : * WITHOUT ANY WARRANTY; without even the implied warranty of
16 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 : : * Lesser General Public License for more details.
18 : : *
19 : : * You should have received a copy of the GNU Lesser General Public
20 : : * License along with this library; if not, write to the Free Software
21 : : * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 : : * 02110-1301 USA
23 : : */
24 : :
25 : : #include "account.h"
26 : : #include "manager.h"
27 : : #include "utils.h"
28 : :
29 : : #undef signals
30 : : #include <libaccounts-glib/ag-manager.h>
31 : : #include <libaccounts-glib/ag-account.h>
32 : :
33 : : namespace Accounts {
34 : :
35 : : /*!
36 : : * @class Watch
37 : : * @headerfile account.h Accounts/Account
38 : : *
39 : : * @brief Monitors an account key or group of keys.
40 : : *
41 : : * @details A watch is created via the Account::watch method and is a simple
42 : : * object which will emit the notify() signal when the value of the key (or
43 : : * group) that it is monitoring is changed.
44 : : */
45 : :
46 : : /*!
47 : : * @class Account
48 : : * @headerfile account.h Accounts/Account
49 : : *
50 : : * @brief The Account class provides an interface to account settings.
51 : : *
52 : : * @details The Account class is used to access the account and service settings.
53 : : * This class has no constructor, therefore to instantiate one Account object
54 : : * one has to either use the Manager::createAccount method (to create a new
55 : : * empty account) or Manager::account (to load an existing account).
56 : : *
57 : : * @attention Do not call setParent() on an account object; the Account class
58 : : * assumes that the parent is always the Manager, and changing it will have
59 : : * unpredictable results.
60 : : *
61 : : * Most of the methods in the Account class act on the selected service: for
62 : : * example, calling setEnabled(false) on the NULL service (this is the service
63 : : * to be used for changing settings globally on the account) will disable the
64 : : * account, while the code
65 : : * \code
66 : : * account->selectService(myService);
67 : : * account->setEnabled(false);
68 : : * \endcode
69 : : * will disable the "myService" service.
70 : : *
71 : : * All changes made on an account (including deletion) are not stored until
72 : : * sync() is called.
73 : : */
74 : :
75 : : class Account::Private
76 : : {
77 : : public:
78 : : Private()
79 : : {
80 : 28 : m_account = 0;
81 : : }
82 : :
83 : 28 : ~Private() {}
84 : :
85 : : AgAccount *m_account; //real account
86 : : QString prefix;
87 : :
88 : : static void on_display_name_changed(Account *self);
89 : : static void on_enabled(Account *self, const gchar *service_name,
90 : : gboolean enabled);
91 : : static void account_store_cb(AgAccount *account, const GError *error,
92 : : Account *self);
93 : : static void on_deleted(Account *self);
94 : : };
95 : :
96 : : class Watch::Private
97 : : {
98 : : public:
99 : : static void account_notify_cb(AgAccount *account, const gchar *key,
100 : : Watch *self);
101 : : };
102 : : } //namespace Accounts
103 : :
104 : :
105 : : using namespace Accounts;
106 : :
107 : 1 : static QChar slash = QChar::fromLatin1('/');
108 : :
109 : : /*!
110 : : * @fn Watch::notify(const char *key)
111 : : *
112 : : * Emitted when the value of the keys monitored by this watch change.
113 : : * @param key The string that was used to create this watch. Note that if
114 : : * this watch is monitor multiple keys this param only identifies their
115 : : * common prefix, and not the actual key being changed.
116 : : */
117 : :
118 : 3 : Watch::Watch(QObject *parent):
119 : 3 : QObject(parent)
120 : : {
121 : 3 : }
122 : :
123 : 3 : Watch::~Watch()
124 : : {
125 : 3 : TRACE();
126 : 3 : Account *account = qobject_cast<Account *>(QObject::parent());
127 : : /* The destructor of Account deletes the child Watches before detaching
128 : : * them, so here account should always be not NULL */
129 : : Q_ASSERT(account != NULL);
130 : 3 : ag_account_remove_watch(account->d->m_account, watch);
131 : 6 : }
132 : :
133 : 1 : void Account::Private::on_display_name_changed(Account *self)
134 : : {
135 : 1 : TRACE();
136 : 1 : const gchar *name = ag_account_get_display_name(self->d->m_account);
137 : :
138 : 1 : emit self->displayNameChanged(UTF8(name));
139 : 1 : }
140 : :
141 : 17 : void Account::Private::on_enabled(Account *self, const gchar *service_name,
142 : : gboolean enabled)
143 : : {
144 : 17 : TRACE();
145 : :
146 : 17 : emit self->enabledChanged(UTF8(service_name), enabled);
147 : 17 : }
148 : :
149 : 2 : void Account::Private::on_deleted(Account *self)
150 : : {
151 : 2 : TRACE();
152 : :
153 : 2 : emit self->removed();
154 : 2 : }
155 : :
156 : : /*!
157 : : * @fn Account::error(Accounts::Error error)
158 : : *
159 : : * Emitted when an error occurs.
160 : : */
161 : :
162 : 28 : Account::Account(AgAccount *account, QObject *parent):
163 : : QObject(parent),
164 : 28 : d(new Private)
165 : : {
166 : 28 : TRACE();
167 : 28 : d->m_account = account;
168 : 28 : g_object_ref(account);
169 : :
170 : : g_signal_connect_swapped(account, "display-name-changed",
171 : : G_CALLBACK(&Private::on_display_name_changed),
172 : 28 : this);
173 : : g_signal_connect_swapped(account, "enabled",
174 : 28 : G_CALLBACK(&Private::on_enabled), this);
175 : : g_signal_connect_swapped(account, "deleted",
176 : 28 : G_CALLBACK(&Private::on_deleted), this);
177 : 28 : }
178 : :
179 : : /*!
180 : : * Destroys the current account object and free all resources.
181 : : */
182 : 28 : Account::~Account()
183 : : {
184 : 28 : TRACE();
185 : :
186 : 28 : QObjectList list = children();
187 [ + + ]: 30 : for (int i = 0; i < list.count(); i++)
188 : : {
189 : 2 : QObject *o = list.at(i);
190 [ + - ]: 2 : if (qobject_cast<Watch *>(o))
191 [ + - ]: 2 : delete o;
192 : : }
193 : :
194 : 28 : g_signal_handlers_disconnect_by_func
195 : 28 : (d->m_account, (void *)&Private::on_display_name_changed, this);
196 : 28 : g_signal_handlers_disconnect_by_func
197 : 28 : (d->m_account, (void *)&Private::on_enabled, this);
198 : 28 : g_signal_handlers_disconnect_by_func
199 : 28 : (d->m_account, (void *)&Private::on_deleted, this);
200 : 28 : g_object_unref(d->m_account);
201 [ + - ]: 28 : delete d;
202 : 28 : d = 0;
203 : 56 : }
204 : :
205 : : /*!
206 : : * Returns the AccountId of this account (0 if the account has not yet been
207 : : * stored into the database).
208 : : */
209 : 11 : AccountId Account::id() const
210 : : {
211 [ + - ]: 11 : return d->m_account ? d->m_account->id : 0;
212 : : }
213 : :
214 : : /*!
215 : : * Returns the Manager.
216 : : */
217 : 6 : Manager *Account::manager() const
218 : : {
219 : 6 : return qobject_cast<Manager *>(QObject::parent());
220 : : }
221 : :
222 : : /*!
223 : : * Checks whether the account supports the given service.
224 : : */
225 : 2 : bool Account::supportsService(const QString &serviceType) const
226 : : {
227 : 2 : TRACE() << serviceType;
228 : :
229 : : return ag_account_supports_service(d->m_account,
230 : 2 : serviceType.toUtf8().constData());
231 : : }
232 : :
233 : : /*!
234 : : * Returns a list of services supported by this account. If the manager was
235 : : * constructed with given service type only the services which supports the
236 : : * service type will be returned.
237 : : *
238 : : * This is currently computed by returning all services having the same
239 : : * provider as the account.
240 : : */
241 : 1 : ServiceList Account::services(const QString &serviceType) const
242 : : {
243 : 1 : TRACE() << serviceType;
244 : :
245 : : GList *list;
246 [ + - ]: 1 : if (serviceType.isEmpty()) {
247 : 1 : list = ag_account_list_services(d->m_account);
248 : : } else {
249 : : list = ag_account_list_services_by_type(d->m_account,
250 : 0 : serviceType.toUtf8().constData());
251 : : }
252 : :
253 : : /* convert glist -> ServiceList */
254 : : ServiceList servList;
255 : : GList *iter;
256 [ + + ]: 2 : for (iter = list; iter; iter = iter->next)
257 : : {
258 : 1 : AgService *service = (AgService*)iter->data;
259 : 1 : servList.append(Service(service, StealReference));
260 : : }
261 : :
262 : 1 : g_list_free(list);
263 : :
264 : 1 : return servList;
265 : : }
266 : :
267 : : /*!
268 : : * Returns a list of enabled services supported by this account. If the manager
269 : : * was constructed with given service type only the services which supports the
270 : : * service type will be returned.
271 : : */
272 : 2 : ServiceList Account::enabledServices() const
273 : : {
274 : : GList *list;
275 : 2 : list = ag_account_list_enabled_services(d->m_account);
276 : :
277 : : /* convert glist -> ServiceList */
278 : : ServiceList servList;
279 : : GList *iter;
280 [ + - ][ + + ]: 3 : for (iter = list; iter; iter = g_list_next(iter))
281 : : {
282 : 1 : AgService *service = (AgService*)iter->data;
283 : 1 : servList.append(Service(service, StealReference));
284 : : }
285 : :
286 : 2 : g_list_free(list);
287 : :
288 : 2 : return servList;
289 : : }
290 : :
291 : : /*!
292 : : * Checks whether the account or selected service is enabled.
293 : : *
294 : : * This method operates on the currently selected service or
295 : : * globally, if none selected.
296 : : */
297 : 2 : bool Account::enabled() const
298 : : {
299 : 2 : return ag_account_get_enabled(d->m_account);
300 : : }
301 : :
302 : : /*!
303 : : * Enables/disables the account or selected service.
304 : : * The change will be written only when sync() is called.
305 : : *
306 : : * This method operates on the currently selected service or
307 : : * globally, if none selected.
308 : : */
309 : 15 : void Account::setEnabled(bool enabled)
310 : : {
311 : 15 : ag_account_set_enabled(d->m_account, enabled);
312 : 15 : }
313 : :
314 : : /*!
315 : : * Returns the display name of the account.
316 : : *
317 : : * This method operates on the currently selected service.
318 : : */
319 : 1 : QString Account::displayName() const
320 : : {
321 : 1 : return UTF8(ag_account_get_display_name(d->m_account));
322 : : }
323 : :
324 : : /*!
325 : : * Changes the display name of the account.
326 : : * The change will be written only when sync() is called.
327 : : */
328 : 1 : void Account::setDisplayName(const QString &displayName)
329 : : {
330 : : ag_account_set_display_name(d->m_account,
331 : 1 : displayName.toUtf8().constData());
332 : 1 : }
333 : :
334 : : /*!
335 : : * Returns the name of the provider of the account.
336 : : */
337 : 2 : QString Account::providerName() const
338 : : {
339 : 2 : return UTF8(ag_account_get_provider_name(d->m_account));
340 : : }
341 : :
342 : : /*!
343 : : * Select the Service for the subsequent operations.
344 : : * @param service The Service to select. If this is invalid, the global
345 : : * account settings will be selected.
346 : : */
347 : 18 : void Account::selectService(const Service &service)
348 : : {
349 : : AgService *agService = NULL;
350 : :
351 [ + + ]: 18 : if (service.isValid())
352 : 12 : agService = service.service();
353 : :
354 : 18 : ag_account_select_service(d->m_account, agService);
355 : 18 : d->prefix = QString();
356 : 18 : }
357 : :
358 : : /*!
359 : : * @return The currently selected service.
360 : : */
361 : 3 : Service Account::selectedService() const
362 : : {
363 : 3 : AgService *agService = ag_account_get_selected_service(d->m_account);
364 : 3 : return Service(agService);
365 : : }
366 : :
367 : : /*!
368 : : * Returns all keys in the current group.
369 : : *
370 : : * This method operates on the currently selected service.
371 : : */
372 : 12 : QStringList Account::allKeys() const
373 : : {
374 : : QStringList allKeys;
375 : : AgAccountSettingIter iter;
376 : : const gchar *key;
377 : : const GValue *val;
378 : :
379 : : /* iterate the settings */
380 : 12 : QByteArray tmp = d->prefix.toLatin1();
381 : 12 : ag_account_settings_iter_init(d->m_account, &iter, tmp.constData());
382 [ + + ]: 71 : while (ag_account_settings_iter_next(&iter, &key, &val))
383 : : {
384 : 59 : allKeys.append(QString(ASCII(key)));
385 : : }
386 : 12 : return allKeys;
387 : : }
388 : :
389 : : /*!
390 : : * Enters a group. This method never fails.
391 : : * @param prefix
392 : : *
393 : : * This method operates on the currently selected service.
394 : : */
395 : 7 : void Account::beginGroup(const QString &prefix)
396 : : {
397 : 7 : d->prefix += prefix + slash;
398 : 7 : }
399 : :
400 : : /*!
401 : : * Returns all the groups which are direct children of the current group.
402 : : *
403 : : * This method operates on the currently selected service.
404 : : */
405 : 2 : QStringList Account::childGroups() const
406 : : {
407 : : QStringList groups, all_keys;
408 : :
409 : 2 : all_keys = allKeys();
410 [ + - ][ + + ]: 15 : foreach (QString key, all_keys)
[ + + ]
411 : : {
412 [ + + ]: 26 : if (key.contains(slash)) {
413 : 8 : QString group = key.section(slash, 0, 0);
414 [ + + ]: 8 : if (!groups.contains(group))
415 : 8 : groups.append(group);
416 : : }
417 : 15 : }
418 : 2 : return groups;
419 : : }
420 : :
421 : : /*!
422 : : * Return all the keys which are direct children of the current group.
423 : : *
424 : : * This method operates on the currently selected service.
425 : : */
426 : 4 : QStringList Account::childKeys() const
427 : : {
428 : : QStringList keys, all_keys;
429 : :
430 : 4 : all_keys = allKeys();
431 [ + - ][ + + ]: 25 : foreach (QString key, all_keys)
[ + + ]
432 : : {
433 [ + + ]: 42 : if (!key.contains(slash))
434 : 9 : keys.append(key);
435 : 25 : }
436 : 4 : return keys;
437 : : }
438 : :
439 : : /*!
440 : : * Removes all the keys in the currently selected service.
441 : : * @see remove(const QString &key)
442 : : */
443 : 1 : void Account::clear()
444 : : {
445 : : /* clear() must ignore the group: so, temporarily reset it and call
446 : : * remove("") */
447 : 1 : QString saved_prefix = d->prefix;
448 : 1 : d->prefix = QString();
449 : 1 : remove(QString());
450 : 1 : d->prefix = saved_prefix;
451 : 1 : }
452 : :
453 : : /*!
454 : : * Checks whether the given key is in the current group.
455 : : * @param key The key name of the settings.
456 : : *
457 : : * This method operates on the currently selected service.
458 : : */
459 : 2 : bool Account::contains(const QString &key) const
460 : : {
461 : 4 : return childKeys().contains(key);
462 : : }
463 : :
464 : : /*!
465 : : * Exits a group.
466 : : *
467 : : * This method operates on the currently selected service.
468 : : */
469 : 5 : void Account::endGroup()
470 : : {
471 : : d->prefix = d->prefix.section(slash, 0, -3,
472 : 5 : QString::SectionIncludeTrailingSep);
473 [ + + ]: 5 : if (d->prefix[0] == slash) d->prefix.remove(0, 1);
474 : 5 : }
475 : :
476 : : /*!
477 : : * Returns the name of the current group.
478 : : *
479 : : * This method operates on the currently selected service.
480 : : */
481 : 4 : QString Account::group() const
482 : : {
483 [ + - ]: 4 : if (d->prefix.endsWith(slash))
484 : 4 : return d->prefix.left(d->prefix.size() - 1);
485 : 0 : return d->prefix;
486 : : }
487 : :
488 : : /*!
489 : : * Checks whether the account is writable. This always returns true.
490 : : */
491 : 0 : bool Account::isWritable() const
492 : : {
493 : 0 : return true;
494 : : }
495 : :
496 : : /*!
497 : : * Removes the given key. If the key is the empty string, all keys in the
498 : : * current group are removed.
499 : : * @param key The key name of the settings.
500 : : *
501 : : * This method operates on the currently selected service.
502 : : */
503 : 11 : void Account::remove(const QString &key)
504 : : {
505 [ + + ]: 11 : if (key.isEmpty())
506 : : {
507 : : /* delete all keys in the group */
508 : 2 : QStringList keys = allKeys();
509 [ + - ][ + + ]: 10 : foreach (QString key, keys)
[ + + ]
510 : : {
511 [ + - ]: 8 : if (!key.isEmpty())
512 : 8 : remove(key);
513 : 10 : }
514 : : }
515 : : else
516 : : {
517 : 9 : QString full_key = d->prefix + key;
518 : 9 : QByteArray tmpkey = full_key.toLatin1();
519 : 9 : ag_account_set_value(d->m_account, tmpkey.constData(), NULL);
520 : : }
521 : 11 : }
522 : :
523 : : /*!
524 : : * Changes the value of an account setting.
525 : : * @param key The key name of the setting.
526 : : * @param value The new value.
527 : : *
528 : : * This method operates on the currently selected service.
529 : : */
530 : 28 : void Account::setValue(const QString &key, const QVariant &value)
531 : : {
532 : 28 : TRACE();
533 : 28 : GValue val= {0, {{0}}};
534 : :
535 [ + - ]: 28 : if (!variantToGValue(value, &val)) {
536 : 28 : return;
537 : : }
538 : :
539 : 28 : QString full_key = d->prefix + key;
540 : 28 : QByteArray tmpkey = full_key.toLatin1();
541 : 28 : ag_account_set_value(d->m_account, tmpkey.constData(), &val);
542 : 28 : g_value_unset(&val);
543 : : }
544 : :
545 : 26 : void Account::Private::account_store_cb(AgAccount *account, const GError *err,
546 : : Account *self)
547 : : {
548 : 26 : TRACE() << "Saved accunt ID:" << account->id;
549 : :
550 [ - + ]: 26 : if (err) {
551 : 0 : emit self->error(Error(err));
552 : : } else {
553 : 26 : emit self->synced();
554 : : }
555 : :
556 : : Q_UNUSED(account);
557 : 26 : }
558 : :
559 : : /*!
560 : : * Retrieves the value of an account setting, as a QVariant.
561 : : * @param key The key whose value must be retrieved.
562 : : * @param value A QVariant initialized to the expected type of the value.
563 : : * @see valueAsString
564 : : * @see valueAsInt
565 : : * @see valueAsBool
566 : : *
567 : : * @return Whether the value comes from the account, the service template
568 : : * or was unset.
569 : : *
570 : : * This method operates on the currently selected service.
571 : : */
572 : 9 : SettingSource Account::value(const QString &key, QVariant &value) const
573 : : {
574 : : GType type;
575 : :
576 [ + - - - : 9 : switch (value.type())
- - + ]
577 : : {
578 : : case QVariant::String:
579 : : type = G_TYPE_STRING;
580 : : break;
581 : : case QVariant::Int:
582 : : type = G_TYPE_INT;
583 : 5 : break;
584 : : case QVariant::UInt:
585 : : type = G_TYPE_UINT;
586 : 0 : break;
587 : : case QVariant::LongLong:
588 : : type = G_TYPE_INT64;
589 : 0 : break;
590 : : case QVariant::ULongLong:
591 : : type = G_TYPE_UINT64;
592 : 0 : break;
593 : : case QVariant::Bool:
594 : : type = G_TYPE_BOOLEAN;
595 : 0 : break;
596 : : default:
597 : 0 : qWarning("Unsupported type %s", value.typeName());
598 : : return NONE;
599 : : }
600 : :
601 : 9 : GValue val= {0, {{0}}};
602 : 9 : g_value_init(&val, type);
603 : 9 : QString full_key = d->prefix + key;
604 : : AgSettingSource source =
605 : : ag_account_get_value(d->m_account,
606 : 9 : full_key.toLatin1().constData(), &val);
607 [ + + ]: 9 : if (source == AG_SETTING_SOURCE_NONE)
608 : : return NONE;
609 : :
610 : 7 : value = gvalueToVariant(&val);
611 : 7 : g_value_unset(&val);
612 : :
613 [ - + ]: 9 : return (source == AG_SETTING_SOURCE_ACCOUNT) ? ACCOUNT : TEMPLATE;
614 : : }
615 : :
616 : : /*!
617 : : * Gets an account setting as a string.
618 : : * @param key The key whose value must be retrieved.
619 : : * @param default_value Value returned if the key is unset.
620 : : * @param source Indicates whether the value comes from the account, the
621 : : * service template or was unset.
622 : : *
623 : : * This method operates on the currently selected service.
624 : : */
625 : 2 : QString Account::valueAsString(const QString &key,
626 : : QString default_value,
627 : : SettingSource *source) const
628 : : {
629 : 2 : QVariant var = default_value;
630 : 2 : SettingSource src = value(key, var);
631 [ - + ]: 2 : if (source)
632 : 0 : *source = src;
633 : 2 : return var.toString();
634 : : }
635 : :
636 : : /*!
637 : : * Gets an account setting as an integer.
638 : : * @param key The key whose value must be retrieved.
639 : : * @param default_value Value returned if the key is unset.
640 : : * @param source Indicates whether the value comes from the account, the
641 : : * service template or was unset.
642 : : *
643 : : * This method operates on the currently selected service.
644 : : */
645 : 0 : int Account::valueAsInt(const QString &key,
646 : : int default_value,
647 : : SettingSource *source) const
648 : : {
649 : 0 : QVariant var = default_value;
650 : 0 : SettingSource src = value(key, var);
651 [ # # ]: 0 : if (source)
652 : 0 : *source = src;
653 : 0 : return var.toInt();
654 : : }
655 : :
656 : : /*!
657 : : * Gets an account setting as an unsigned long integer.
658 : : * @param key The key of which value must be retrieved.
659 : : * @param default_value Value returned if the key is unset.
660 : : * @param source Indicates whether the value comes from the account, the
661 : : * service template or was unset.
662 : : *
663 : : * This method operates on the currently selected service.
664 : : */
665 : 0 : quint64 Account::valueAsUInt64(const QString &key,
666 : : quint64 default_value,
667 : : SettingSource *source) const
668 : : {
669 : 0 : QVariant var = default_value;
670 : 0 : SettingSource src = value(key, var);
671 [ # # ]: 0 : if (source)
672 : 0 : *source = src;
673 : 0 : return var.toULongLong();
674 : : }
675 : :
676 : : /*!
677 : : * Gets an account setting as a boolean.
678 : : * @param key The key whose value must be retrieved.
679 : : * @param default_value Value returned if the key is unset.
680 : : * @param source Indicates whether the value comes from the account, the
681 : : * service template or was unset.
682 : : *
683 : : * This method operates on the currently selected service.
684 : : */
685 : 0 : bool Account::valueAsBool(const QString &key,
686 : : bool default_value,
687 : : SettingSource *source) const
688 : : {
689 : 0 : QVariant var = default_value;
690 : 0 : SettingSource src = value(key, var);
691 [ # # ]: 0 : if (source)
692 : 0 : *source = src;
693 : 0 : return var.toBool();
694 : : }
695 : :
696 : 6 : void Watch::Private::account_notify_cb(AgAccount *account, const gchar *key,
697 : : Watch *watch)
698 : : {
699 : 6 : emit watch->notify(key);
700 : :
701 : : Q_UNUSED(account);
702 : 6 : }
703 : :
704 : : /*!
705 : : * Installs a key or group watch.
706 : : *
707 : : * @param key The key to watch; if %NULL, watches the currently selected
708 : : * group.
709 : : *
710 : : * @return A watch object.
711 : : *
712 : : * This method operates on the currently selected service.
713 : : */
714 : 3 : Watch *Account::watchKey(const QString &key)
715 : : {
716 : : AgAccountWatch ag_watch;
717 : 3 : Watch *watch = new Watch(this);
718 : :
719 [ + + ]: 3 : if (!key.isEmpty())
720 : : {
721 : 2 : QString full_key = d->prefix + key;
722 : : ag_watch = ag_account_watch_key
723 : : (d->m_account, full_key.toLatin1().constData(),
724 : 2 : (AgAccountNotifyCb)&Watch::Private::account_notify_cb, watch);
725 : : }
726 : : else
727 : : {
728 : : ag_watch = ag_account_watch_dir
729 : : (d->m_account, d->prefix.toLatin1().constData(),
730 : 1 : (AgAccountNotifyCb)&Watch::Private::account_notify_cb, watch);
731 : : }
732 : :
733 [ - + ]: 3 : if (!ag_watch)
734 : : {
735 [ # # ]: 0 : delete watch;
736 : : return NULL;
737 : : }
738 : :
739 : : watch->setWatch(ag_watch);
740 : 3 : return watch;
741 : : }
742 : :
743 : : /*!
744 : : * Stores all account settings into the database.
745 : : * The signal synced() will be emitted in case of success, or
746 : : * error() in case of failure. No assumption must be made about when these
747 : : * signals will be emitted: if the database is locked, the signals might
748 : : * be emitted asynchronously, whereas if the operation can happen
749 : : * synchronously then the signals can be emitted before this method
750 : : * returns.
751 : : * If for some reason one would want to process the signals asynchronously
752 : : * from the event loop, one can use the Qt::QueuedConnection connection
753 : : * type as last parameter of the QObject::connect call.
754 : : */
755 : 26 : void Account::sync()
756 : : {
757 : 26 : TRACE();
758 : :
759 : : ag_account_store(d->m_account,
760 : : (AgAccountStoreCb)&Private::account_store_cb,
761 : 26 : this);
762 : 26 : }
763 : :
764 : : /*!
765 : : * Blocking version of the sync() method: execution of the current thread
766 : : * will block until the operation has completed.
767 : : * Usage of this method is discouraged, especially for UI applications.
768 : : *
769 : : * @return True on success, false otherwise.
770 : : */
771 : 9 : bool Account::syncAndBlock()
772 : : {
773 : 9 : TRACE();
774 : :
775 : 9 : GError *error = NULL;
776 : : bool ret;
777 : :
778 : 9 : ret = ag_account_store_blocking(d->m_account, &error);
779 [ - + ]: 9 : if (error)
780 : : {
781 : 0 : qWarning() << "Store operation failed: " << error->message;
782 : 0 : g_error_free(error);
783 : : }
784 : :
785 : 9 : return ret;
786 : : }
787 : :
788 : : /*!
789 : : * Marks the account for removal.
790 : : * The account will be deleted only when the sync() method is called.
791 : : */
792 : 2 : void Account::remove()
793 : : {
794 : 2 : TRACE();
795 : 2 : ag_account_delete(d->m_account);
796 : 2 : }
797 : :
798 : : /*!
799 : : * Creates signature of key with given aegis token. The calling application
800 : : * must possess (request) the given aegis token. The account needs to be
801 : : * stored prior to executing this method.
802 : : * @param key The key or the prefix of set of the keys to be signed.
803 : : * @param token The aegis token to be used for signing the key.
804 : : *
805 : : * This method operates on the currently selected service.
806 : : */
807 : 0 : void Account::sign(const QString &key, const char *token)
808 : : {
809 : 0 : ag_account_sign (d->m_account, key.toUtf8().constData(), token);
810 : 0 : }
811 : :
812 : : /*!
813 : : * Verifies if the key is signed and the signature matches the value
814 : : * and provides the aegis token which was used for signing the key.
815 : : *
816 : : * @param key The name of the key or prefix of the keys to be verified.
817 : : * @param token Aegis token to be retrieved.
818 : : *
819 : : * @return True if the key is signed and the signature matches the value.
820 : : *
821 : : * This method operates on the currently selected service.
822 : : */
823 : 0 : bool Account::verify(const QString &key, const char **token)
824 : : {
825 : 0 : return ag_account_verify(d->m_account, key.toUtf8().constData(), token);
826 : : }
827 : :
828 : : /*!
829 : : * Verifies if the key is signed with any of the aegis tokens and the
830 : : * signature is valid.
831 : : *
832 : : * @param key The name of the key or prefix of the keys to be verified.
833 : : * @param tokens Array of aegis tokens.
834 : : *
835 : : * @return True if the key is signed with any of the aegis tokens and
836 : : * the signature is valid.
837 : : *
838 : : * This method operates on the currently selected service.
839 : : */
840 : 0 : bool Account::verifyWithTokens(const QString &key, QList<const char*> tokens)
841 : : {
842 : : int tokensCount = tokens.count();
843 : :
844 : 0 : const char *tmp[tokensCount + 1];
845 : :
846 [ # # ]: 0 : for (int i = 0; i < tokensCount; ++i)
847 : : {
848 : 0 : tmp[i] = tokens.at(i);
849 : : }
850 : 0 : tmp[tokensCount] = NULL;
851 : :
852 : 0 : return ag_account_verify_with_tokens(d->m_account, key.toUtf8().constData(), tmp);
853 : : }
854 : :
855 : 3 : uint Account::credentialsId()
856 : : {
857 : 3 : QString key = ACCOUNTS_KEY_CREDENTIALS_ID;
858 : 3 : QVariant val(QVariant::Int);
859 : :
860 [ + + ]: 3 : if (value(key, val) != NONE)
861 : 2 : return val.toUInt();
862 : :
863 : : uint id = 0;
864 : 1 : Service service = selectedService();
865 [ + - ]: 1 : if (service.isValid()) {
866 : 1 : selectService();
867 [ + - ]: 1 : if (value(key, val) != NONE)
868 : 1 : id = val.toUInt();
869 : 1 : selectService(service);
870 : : }
871 : 3 : return id;
872 : : }
873 : :
874 : 2 : AgAccount *Account::account()
875 : : {
876 : 2 : return d->m_account;
877 : 1 : }
|