• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.10.5 API Reference
  • KDE Home
  • Contact Us
 

KDEUI

  • kdeui
  • util
kwallet.cpp
Go to the documentation of this file.
1 /* This file is part of the KDE project
2  *
3  * Copyright (C) 2002-2004 George Staikos <staikos@kde.org>
4  * Copyright (C) 2008 Michael Leupold <lemma@confuego.org>
5  * Copyright (C) 2011 Valentin Rusu <kde@rusu.info>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public License
18  * along with this library; see the file COPYING.LIB. If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 #include "kwallet.h"
24 #include "config-kwallet.h"
25 
26 #include <QtGui/QApplication>
27 #include <QtCore/QPointer>
28 #include <QtGui/QWidget>
29 #include <QtDBus/QtDBus>
30 #include <ktoolinvocation.h>
31 
32 #include <assert.h>
33 #include <kcomponentdata.h>
34 #include <kconfiggroup.h>
35 #include <kdebug.h>
36 #include <kdeversion.h>
37 #include <kglobal.h>
38 #include <kaboutdata.h>
39 #include <ksharedconfig.h>
40 #include <kwindowsystem.h>
41 
42 #ifdef HAVE_KSECRETSSERVICE
43 #include "ksecretsservice/ksecretsservicecollection.h"
44 #endif
45 
46 #include "kwallet_interface.h"
47 
48 #ifdef HAVE_KSECRETSSERVICE
49 typedef QMap<QString, KSecretsService::StringStringMap> StringToStringStringMapMap;
50 Q_DECLARE_METATYPE(StringToStringStringMapMap)
51 #endif
52 typedef QMap<QString, QByteArray> StringByteArrayMap;
53 Q_DECLARE_METATYPE(StringByteArrayMap)
54 
55 namespace KWallet
56 {
57 
58 class KWalletDLauncher
59 {
60 public:
61  KWalletDLauncher();
62  ~KWalletDLauncher();
63  org::kde::KWallet &getInterface();
64 
65  // this static variable is used below to switch between old KWallet
66  // infrastructure and the new one which is built on top of the new
67  // KSecretsService infrastructure. It's value can be changed via the
68  // the Wallet configuration module in System Settings
69  bool m_useKSecretsService;
70  org::kde::KWallet *m_wallet;
71  KConfigGroup m_cgroup;
72 };
73 
74 K_GLOBAL_STATIC(KWalletDLauncher, walletLauncher)
75 
76 static QString appid()
77 {
78  if (KGlobal::hasMainComponent()) {
79  KComponentData cData = KGlobal::mainComponent();
80  if (cData.isValid()) {
81  const KAboutData* aboutData = cData.aboutData();
82  if (aboutData) {
83  return aboutData->programName();
84  }
85  return cData.componentName();
86  }
87  }
88  return qApp->applicationName();
89 }
90 
91 static void registerTypes()
92 {
93  static bool registered = false;
94  if (!registered) {
95 #ifdef HAVE_KSECRETSSERVICE
96  qDBusRegisterMetaType<KSecretsService::StringStringMap>();
97  qDBusRegisterMetaType<StringToStringStringMapMap>();
98 #endif
99  qDBusRegisterMetaType<StringByteArrayMap>();
100  registered = true;
101  }
102 }
103 
104 bool Wallet::isUsingKSecretsService()
105 {
106  return walletLauncher->m_useKSecretsService;
107 }
108 
109 const QString Wallet::LocalWallet() {
110  // NOTE: This method stays unchanged for KSecretsService
111  KConfigGroup cfg(KSharedConfig::openConfig("kwalletrc")->group("Wallet"));
112  if (!cfg.readEntry("Use One Wallet", true)) {
113  QString tmp = cfg.readEntry("Local Wallet", "localwallet");
114  if (tmp.isEmpty()) {
115  return "localwallet";
116  }
117  return tmp;
118  }
119 
120  QString tmp = cfg.readEntry("Default Wallet", "kdewallet");
121  if (tmp.isEmpty()) {
122  return "kdewallet";
123  }
124  return tmp;
125 }
126 
127 const QString Wallet::NetworkWallet() {
128  // NOTE: This method stays unchanged for KSecretsService
129  KConfigGroup cfg(KSharedConfig::openConfig("kwalletrc")->group("Wallet"));
130 
131  QString tmp = cfg.readEntry("Default Wallet", "kdewallet");
132  if (tmp.isEmpty()) {
133  return "kdewallet";
134  }
135  return tmp;
136 }
137 
138 const QString Wallet::PasswordFolder() {
139  return "Passwords";
140 }
141 
142 const QString Wallet::FormDataFolder() {
143  return "Form Data";
144 }
145 
146 class Wallet::WalletPrivate
147 {
148 public:
149  WalletPrivate(Wallet *wallet, int h, const QString &n)
150  : q(wallet), name(n), handle(h)
151 #ifdef HAVE_KSECRETSSERVICE
152  , secretsCollection(0)
153 #endif
154  {}
155 
156  void walletServiceUnregistered();
157 
158 #ifdef HAVE_KSECRETSSERVICE
159  template <typename T>
160  int writeEntry( const QString& key, const T &value, Wallet::EntryType entryType ) {
161  int rc = -1;
162  KSecretsService::Secret secret;
163  secret.setValue( QVariant::fromValue<T>(value) );
164 
165  KSecretsService::StringStringMap attrs;
166  attrs[KSS_ATTR_ENTRYFOLDER] = folder;
167  attrs[KSS_ATTR_WALLETTYPE] = QString("%1").arg((int)entryType);
168  KSecretsService::CreateCollectionItemJob *createItemJob = secretsCollection->createItem( key, attrs, secret );
169 
170  if ( !createItemJob->exec() ) {
171  kDebug(285) << "Cannot execute CreateCollectionItemJob : " << createItemJob->errorString();
172  }
173  rc = createItemJob->error();
174  return rc;
175  }
176 
177  QExplicitlySharedDataPointer<KSecretsService::SecretItem> findItem( const QString& key ) const;
178  template <typename T> int readEntry( const QString& key, T& value ) const;
179  bool readSecret( const QString& key, KSecretsService::Secret& value ) const;
180 
181  template <typename V>
182  int forEachItemThatMatches( const QString &key, V verb ) {
183  int rc = -1;
184  KSecretsService::StringStringMap attrs;
185  attrs[KSS_ATTR_ENTRYFOLDER] = folder;
186  KSecretsService::SearchCollectionItemsJob *searchItemsJob = secretsCollection->searchItems(attrs);
187  if ( searchItemsJob->exec() ) {
188  QRegExp re(key, Qt::CaseSensitive, QRegExp::Wildcard);
189  foreach( KSecretsService::SearchCollectionItemsJob::Item item , searchItemsJob->items() ) {
190  KSecretsService::ReadItemPropertyJob *readLabelJob = item->label();
191  if ( readLabelJob->exec() ) {
192  QString label = readLabelJob->propertyValue().toString();
193  if ( re.exactMatch( label ) ) {
194  if ( verb( this, label, item.data() ) ) {
195  rc = 0; // one successfull iteration already produced results, so success return
196  }
197  }
198  }
199  else {
200  kDebug(285) << "Cannot execute ReadItemPropertyJob " << readLabelJob->errorString();
201  }
202  }
203  }
204  else {
205  kDebug(285) << "Cannot execute KSecretsService::SearchCollectionItemsJob " << searchItemsJob->errorString();
206  }
207  return rc;
208  }
209 
210  void createDefaultFolders();
211 
212  struct InsertIntoEntryList;
213  struct InsertIntoMapList;
214  struct InsertIntoPasswordList;
215 
216  KSecretsService::Collection *secretsCollection;
217 #endif // HAVE_KSECRETSSERVICE
218 
219  Wallet *q;
220  QString name;
221  QString folder;
222  int handle;
223  int transactionId;
224  QPointer<QEventLoop> loop;
225 };
226 
227 #ifdef HAVE_KSECRETSSERVICE
228 void Wallet::WalletPrivate::createDefaultFolders()
229 {
230 // NOTE: KWalletManager expects newly created wallets to have two default folders
231 // b->createFolder(KWallet::Wallet::PasswordFolder());
232 // b->createFolder(KWallet::Wallet::FormDataFolder());
233  QString strDummy("");
234  folder = PasswordFolder();
235  writeEntry( PasswordFolder(), strDummy, KWallet::Wallet::Unknown );
236 
237  folder = FormDataFolder();
238  writeEntry( FormDataFolder(), strDummy, KWallet::Wallet::Unknown );
239 }
240 #endif // HAVE_KSECRETSSERVICE
241 
242 static const char s_kwalletdServiceName[] = "org.kde.kwalletd";
243 
244 Wallet::Wallet(int handle, const QString& name)
245  : QObject(0L), d(new WalletPrivate(this, handle, name))
246 {
247  if (walletLauncher->m_useKSecretsService) {
248  // see openWallet for initialization code; this constructor does not have any code
249  }
250  else {
251  QDBusServiceWatcher *watcher = new QDBusServiceWatcher(QString::fromLatin1(s_kwalletdServiceName), QDBusConnection::sessionBus(),
252  QDBusServiceWatcher::WatchForUnregistration, this);
253  connect(watcher, SIGNAL(serviceUnregistered(QString)),
254  this, SLOT(walletServiceUnregistered()));
255 
256  connect(&walletLauncher->getInterface(), SIGNAL(walletClosed(int)), SLOT(slotWalletClosed(int)));
257  connect(&walletLauncher->getInterface(), SIGNAL(folderListUpdated(QString)), SLOT(slotFolderListUpdated(QString)));
258  connect(&walletLauncher->getInterface(), SIGNAL(folderUpdated(QString,QString)), SLOT(slotFolderUpdated(QString,QString)));
259  connect(&walletLauncher->getInterface(), SIGNAL(applicationDisconnected(QString,QString)), SLOT(slotApplicationDisconnected(QString,QString)));
260 
261  // Verify that the wallet is still open
262  if (d->handle != -1) {
263  QDBusReply<bool> r = walletLauncher->getInterface().isOpen(d->handle);
264  if (r.isValid() && !r) {
265  d->handle = -1;
266  d->name.clear();
267  }
268  }
269  }
270 }
271 
272 
273 Wallet::~Wallet() {
274 #ifdef HAVE_KSECRETSSERVICE
275  if (walletLauncher->m_useKSecretsService) {
276  d->folder.clear();
277  d->name.clear();
278  delete d->secretsCollection;
279  }
280  else {
281 #endif
282  if (d->handle != -1) {
283  if (!walletLauncher.isDestroyed()) {
284  walletLauncher->getInterface().close(d->handle, false, appid());
285  } else {
286  kDebug(285) << "Problem with static destruction sequence."
287  "Destroy any static Wallet before the event-loop exits.";
288  }
289  d->handle = -1;
290  d->folder.clear();
291  d->name.clear();
292  }
293 #ifdef HAVE_KSECRETSSERVICE
294  }
295 #endif
296  delete d;
297 }
298 
299 
300 QStringList Wallet::walletList() {
301  QStringList result;
302 #ifdef HAVE_KSECRETSSERVICE
303  if (walletLauncher->m_useKSecretsService) {
304  KSecretsService::ListCollectionsJob *listJob = KSecretsService::Collection::listCollections();
305  if ( listJob->exec() ) {
306  result = listJob->collections();
307  }
308  else {
309  kDebug(285) << "Cannot execute ListCollectionsJob: " << listJob->errorString();
310  }
311  }
312  else {
313 #endif
314  QDBusReply<QStringList> r = walletLauncher->getInterface().wallets();
315 
316  if (!r.isValid())
317  {
318  kDebug(285) << "Invalid DBus reply: " << r.error();
319  }
320  else
321  result = r;
322 #ifdef HAVE_KSECRETSSERVICE
323  }
324 #endif
325  return result;
326 }
327 
328 
329 void Wallet::changePassword(const QString& name, WId w) {
330  if( w == 0 )
331  kDebug(285) << "Pass a valid window to KWallet::Wallet::changePassword().";
332 
333  // Make sure the password prompt window will be visible and activated
334  KWindowSystem::allowExternalProcessWindowActivation();
335 #ifdef HAVE_KSECRETSSERVICE
336  if (walletLauncher->m_useKSecretsService) {
337  KSecretsService::Collection *coll = KSecretsService::Collection::findCollection( name );
338  KSecretsService::ChangeCollectionPasswordJob* changePwdJob = coll->changePassword();
339  if ( !changePwdJob->exec() ) {
340  kDebug(285) << "Cannot execute change password job: " << changePwdJob->errorString();
341  }
342  coll->deleteLater();
343  }
344  else {
345 #endif
346  walletLauncher->getInterface().changePassword(name, (qlonglong)w, appid());
347 #ifdef HAVE_KSECRETSSERVICE
348  }
349 #endif
350 }
351 
352 
353 bool Wallet::isEnabled() {
354 #ifdef HAVE_KSECRETSSERVICE
355  if (walletLauncher->m_useKSecretsService) {
356  return walletLauncher->m_cgroup.readEntry("Enabled", true);
357  }
358  else {
359 #endif
360  QDBusReply<bool> r = walletLauncher->getInterface().isEnabled();
361 
362  if (!r.isValid())
363  {
364  kDebug(285) << "Invalid DBus reply: " << r.error();
365  return false;
366  }
367  else
368  return r;
369 #ifdef HAVE_KSECRETSSERVICE
370  }
371 #endif
372 }
373 
374 
375 bool Wallet::isOpen(const QString& name) {
376 #ifdef HAVE_KSECRETSSERVICE
377  if (walletLauncher->m_useKSecretsService) {
378  KSecretsService::Collection *coll = KSecretsService::Collection::findCollection( name, KSecretsService::Collection::OpenOnly );
379  KSecretsService::ReadCollectionPropertyJob *readLocked = coll->isLocked();
380  if ( readLocked->exec() ) {
381  return !readLocked->propertyValue().toBool();
382  }
383  else {
384  kDebug() << "ReadLocked job failed";
385  return false;
386  }
387  }
388  else {
389 #endif
390  QDBusReply<bool> r = walletLauncher->getInterface().isOpen(name);
391 
392  if (!r.isValid())
393  {
394  kDebug(285) << "Invalid DBus reply: " << r.error();
395  return false;
396  }
397  else
398  return r;
399 #ifdef HAVE_KSECRETSSERVICE
400  }
401 #endif
402 }
403 
404 int Wallet::closeWallet(const QString& name, bool force) {
405 #ifdef HAVE_KSECRETSSERVICE
406  if (walletLauncher->m_useKSecretsService) {
407  kDebug(285) << "Wallet::closeWallet NOOP";
408  return 0;
409  }
410  else {
411 #endif
412  QDBusReply<int> r = walletLauncher->getInterface().close(name, force);
413 
414  if (!r.isValid())
415  {
416  kDebug(285) << "Invalid DBus reply: " << r.error();
417  return -1;
418  }
419  else
420  return r;
421 #ifdef HAVE_KSECRETSSERVICE
422  }
423 #endif
424 }
425 
426 
427 int Wallet::deleteWallet(const QString& name) {
428 #ifdef HAVE_KSECRETSSERVICE
429  if (walletLauncher->m_useKSecretsService) {
430  KSecretsService::Collection *coll = KSecretsService::Collection::findCollection(name, KSecretsService::Collection::OpenOnly);
431  KJob *deleteJob = coll->deleteCollection();
432  if (!deleteJob->exec()) {
433  kDebug(285) << "Cannot execute delete job " << deleteJob->errorString();
434  }
435  return deleteJob->error();
436  }
437  else {
438 #endif
439  QDBusReply<int> r = walletLauncher->getInterface().deleteWallet(name);
440 
441  if (!r.isValid())
442  {
443  kDebug(285) << "Invalid DBus reply: " << r.error();
444  return -1;
445  }
446  else
447  return r;
448 #ifdef HAVE_KSECRETSSERVICE
449  }
450 #endif
451 }
452 
453 Wallet *Wallet::openWallet(const QString& name, WId w, OpenType ot) {
454  if( w == 0 )
455  kDebug(285) << "Pass a valid window to KWallet::Wallet::openWallet().";
456 
457 #ifdef HAVE_KSECRETSSERVICE
458  if (walletLauncher->m_useKSecretsService) {
459  Wallet *wallet = new Wallet(-1, name);
460  // FIXME: should we specify CreateCollection or OpenOnly here?
461  wallet->d->secretsCollection = KSecretsService::Collection::findCollection(name, KSecretsService::Collection::CreateCollection, QVariantMap(), w);
462  connect( wallet->d->secretsCollection, SIGNAL(statusChanged(int)), wallet, SLOT(slotCollectionStatusChanged(int)) );
463  connect( wallet->d->secretsCollection, SIGNAL(deleted()), wallet, SLOT(slotCollectionDeleted()) );
464  if ( ot == Synchronous ) {
465  kDebug() << "WARNING openWallet OpenType=Synchronous requested";
466  // TODO: not sure what to do with in this case; however, all other KSecretsService API methods are already
467  // async and will perform sync inside this API because of it's design
468  }
469  return wallet;
470  }
471  else {
472 #endif
473  Wallet *wallet = new Wallet(-1, name);
474 
475  // connect the daemon's opened signal to the slot filtering the
476  // signals we need
477  connect(&walletLauncher->getInterface(), SIGNAL(walletAsyncOpened(int,int)),
478  wallet, SLOT(walletAsyncOpened(int,int)));
479 
480  // Use an eventloop for synchronous calls
481  QEventLoop loop;
482  if (ot == Synchronous || ot == Path) {
483  connect(wallet, SIGNAL(walletOpened(bool)), &loop, SLOT(quit()));
484  }
485 
486  // Make sure the password prompt window will be visible and activated
487  KWindowSystem::allowExternalProcessWindowActivation();
488 
489  // do the call
490  QDBusReply<int> r;
491  if (ot == Synchronous || ot == Asynchronous) {
492  r = walletLauncher->getInterface().openAsync(name, (qlonglong)w, appid(), true);
493  } else if (ot == Path) {
494  r = walletLauncher->getInterface().openPathAsync(name, (qlonglong)w, appid(), true);
495  } else {
496  delete wallet;
497  return 0;
498  }
499  // error communicating with the daemon (maybe not running)
500  if (!r.isValid()) {
501  kDebug(285) << "Invalid DBus reply: " << r.error();
502  delete wallet;
503  return 0;
504  }
505  wallet->d->transactionId = r.value();
506 
507  if (ot == Synchronous || ot == Path) {
508  // check for an immediate error
509  if (wallet->d->transactionId < 0) {
510  delete wallet;
511  wallet = 0;
512  } else {
513  // wait for the daemon's reply
514  // store a pointer to the event loop so it can be quit in error case
515  wallet->d->loop = &loop;
516  loop.exec();
517  if (wallet->d->handle < 0) {
518  delete wallet;
519  return 0;
520  }
521  }
522  } else if (ot == Asynchronous) {
523  if (wallet->d->transactionId < 0) {
524  QTimer::singleShot(0, wallet, SLOT(emitWalletAsyncOpenError()));
525  // client code is responsible for deleting the wallet
526  }
527  }
528 
529  return wallet;
530 #ifdef HAVE_KSECRETSSERVICE
531  }
532 #endif
533 }
534 
535 void Wallet::slotCollectionStatusChanged(int status)
536 {
537 #ifdef HAVE_KSECRETSSERVICE
538  KSecretsService::Collection::Status collStatus = (KSecretsService::Collection::Status)status;
539  switch ( collStatus ) {
540  case KSecretsService::Collection::NewlyCreated:
541  d->createDefaultFolders();
542  // fall through
543  case KSecretsService::Collection::FoundExisting:
544  emitWalletOpened();
545  break;
546  case KSecretsService::Collection::Deleted:
547  case KSecretsService::Collection::Invalid:
548  case KSecretsService::Collection::Pending:
549  // nothing to do
550  break;
551  case KSecretsService::Collection::NotFound:
552  emitWalletAsyncOpenError();
553  break;
554  }
555 #endif
556 }
557 
558 void Wallet::slotCollectionDeleted()
559 {
560  d->folder.clear();
561  d->name.clear();
562  emit walletClosed();
563 }
564 
565 bool Wallet::disconnectApplication(const QString& wallet, const QString& app) {
566 #ifdef HAVE_KSECRETSSERVICE
567  if (walletLauncher->m_useKSecretsService) {
568  kDebug() << "Wallet::disconnectApplication NOOP";
569  return true;
570  }
571  else {
572 #endif
573  QDBusReply<bool> r = walletLauncher->getInterface().disconnectApplication(wallet, app);
574 
575  if (!r.isValid())
576  {
577  kDebug(285) << "Invalid DBus reply: " << r.error();
578  return false;
579  }
580  else
581  return r;
582 #ifdef HAVE_KSECRETSSERVICE
583  }
584 #endif
585 }
586 
587 
588 QStringList Wallet::users(const QString& name) {
589 #ifdef HAVE_KSECRETSSERVICE
590  if (walletLauncher->m_useKSecretsService) {
591  kDebug() << "KSecretsService does not handle users list";
592  return QStringList();
593  }
594  else {
595 #endif
596  QDBusReply<QStringList> r = walletLauncher->getInterface().users(name);
597  if (!r.isValid())
598  {
599  kDebug(285) << "Invalid DBus reply: " << r.error();
600  return QStringList();
601  }
602  else
603  return r;
604 #ifdef HAVE_KSECRETSSERVICE
605  }
606 #endif
607 }
608 
609 
610 int Wallet::sync() {
611 #ifdef HAVE_KSECRETSSERVICE
612  if (walletLauncher->m_useKSecretsService) {
613  // NOOP with KSecretsService
614  }
615  else {
616 #endif
617  if (d->handle == -1) {
618  return -1;
619  }
620 
621  walletLauncher->getInterface().sync(d->handle, appid());
622 #ifdef HAVE_KSECRETSSERVICE
623  }
624 #endif
625  return 0;
626 }
627 
628 
629 int Wallet::lockWallet() {
630 #ifdef HAVE_KSECRETSSERVICE
631  if (walletLauncher->m_useKSecretsService) {
632  KSecretsService::CollectionLockJob *lockJob = d->secretsCollection->lock();
633  if (lockJob->exec()) {
634  d->folder.clear();
635  d->name.clear();
636  }
637  else {
638  kDebug(285) << "Cannot execute KSecretsService::CollectionLockJob : " << lockJob->errorString();
639  return -1;
640  }
641  return lockJob->error();
642  }
643  else {
644 #endif
645  if (d->handle == -1) {
646  return -1;
647  }
648 
649  QDBusReply<int> r = walletLauncher->getInterface().close(d->handle, true, appid());
650  d->handle = -1;
651  d->folder.clear();
652  d->name.clear();
653  if (r.isValid()) {
654  return r;
655  }
656  else {
657  kDebug(285) << "Invalid DBus reply: " << r.error();
658  return -1;
659  }
660 #ifdef HAVE_KSECRETSSERVICE
661  }
662 #endif
663 }
664 
665 
666 const QString& Wallet::walletName() const {
667  return d->name;
668 }
669 
670 
671 bool Wallet::isOpen() const {
672 #ifdef HAVE_KSECRETSSERVICE
673  if (walletLauncher->m_useKSecretsService) {
674  return !d->secretsCollection->isLocked();
675  }
676  else {
677 #endif
678  return d->handle != -1;
679 #ifdef HAVE_KSECRETSSERVICE
680  }
681 #endif
682 }
683 
684 
685 void Wallet::requestChangePassword(WId w) {
686  if( w == 0 )
687  kDebug(285) << "Pass a valid window to KWallet::Wallet::requestChangePassword().";
688 
689 #ifdef HAVE_KSECRETSSERVICE
690  if (walletLauncher->m_useKSecretsService) {
691  KSecretsService::ChangeCollectionPasswordJob *changePwdJob = d->secretsCollection->changePassword();
692  if (!changePwdJob->exec()) {
693  kDebug(285) << "Cannot execute ChangeCollectionPasswordJob : " << changePwdJob->errorString();
694  }
695  }
696  else {
697 #endif
698  if (d->handle == -1) {
699  return;
700  }
701 
702  // Make sure the password prompt window will be visible and activated
703  KWindowSystem::allowExternalProcessWindowActivation();
704 
705  walletLauncher->getInterface().changePassword(d->name, (qlonglong)w, appid());
706 #ifdef HAVE_KSECRETSSERVICE
707  }
708 #endif
709 }
710 
711 
712 void Wallet::slotWalletClosed(int handle) {
713 #ifdef HAVE_KSECRETSSERVICE
714  if (walletLauncher->m_useKSecretsService) {
715  // TODO: implement this
716  Q_ASSERT(0);
717  }
718  else {
719 #endif
720  if (d->handle == handle) {
721  d->handle = -1;
722  d->folder.clear();
723  d->name.clear();
724  emit walletClosed();
725  }
726 #ifdef HAVE_KSECRETSSERVICE
727  }
728 #endif
729 }
730 
731 
732 QStringList Wallet::folderList() {
733 #ifdef HAVE_KSECRETSSERVICE
734  if (walletLauncher->m_useKSecretsService) {
735  QStringList result;
736 
737  KSecretsService::StringStringMap attrs;
738  attrs[KSS_ATTR_ENTRYFOLDER] = ""; // search for items having this attribute no matter what value it has
739  KSecretsService::SearchCollectionItemsJob *searchJob = d->secretsCollection->searchItems(attrs);
740 
741  if (searchJob->exec()) {
742  KSecretsService::ReadCollectionItemsJob::ItemList itemList = searchJob->items();
743  foreach( const KSecretsService::ReadCollectionItemsJob::Item &item, itemList ) {
744  KSecretsService::ReadItemPropertyJob *readAttrsJob = item->attributes();
745  if (readAttrsJob->exec()) {
746  KSecretsService::StringStringMap attrs = readAttrsJob->propertyValue().value<KSecretsService::StringStringMap>();
747  const QString folder = attrs[KSS_ATTR_ENTRYFOLDER];
748  if (!folder.isEmpty() && !result.contains(folder)) {
749  result.append(folder);
750  }
751  }
752  else {
753  kDebug(285) << "Cannot read item attributes : " << readAttrsJob->errorString();
754  }
755  }
756  }
757  else {
758  kDebug(285) << "Cannot execute ReadCollectionItemsJob : " << searchJob->errorString();
759  }
760  return result;
761  }
762  else {
763 #endif
764  if (d->handle == -1) {
765  return QStringList();
766  }
767 
768  QDBusReply<QStringList> r = walletLauncher->getInterface().folderList(d->handle, appid());
769  if (!r.isValid())
770  {
771  kDebug(285) << "Invalid DBus reply: " << r.error();
772  return QStringList();
773  }
774  else
775  return r;
776 #ifdef HAVE_KSECRETSSERVICE
777  }
778 #endif
779 }
780 
781 
782 QStringList Wallet::entryList() {
783 #ifdef HAVE_KSECRETSSERVICE
784  if (walletLauncher->m_useKSecretsService) {
785  QStringList result;
786  KSecretsService::StringStringMap attrs;
787  attrs[KSS_ATTR_ENTRYFOLDER] = d->folder;
788  KSecretsService::SearchCollectionItemsJob *readItemsJob = d->secretsCollection->searchItems( attrs );
789  if ( readItemsJob->exec() ) {
790  foreach( KSecretsService::SearchCollectionItemsJob::Item item, readItemsJob->items() ) {
791  KSecretsService::ReadItemPropertyJob *readLabelJob = item->label();
792  if ( readLabelJob->exec() ) {
793  result.append( readLabelJob->propertyValue().toString() );
794  }
795  else {
796  kDebug(285) << "Cannot execute readLabelJob" << readItemsJob->errorString();
797  }
798  }
799  }
800  else {
801  kDebug(285) << "Cannot execute readItemsJob" << readItemsJob->errorString();
802  }
803  return result;
804  }
805  else {
806 #endif
807  if (d->handle == -1) {
808  return QStringList();
809  }
810 
811  QDBusReply<QStringList> r = walletLauncher->getInterface().entryList(d->handle, d->folder, appid());
812  if (!r.isValid())
813  {
814  kDebug(285) << "Invalid DBus reply: " << r.error();
815  return QStringList();
816  }
817  else
818  return r;
819 #ifdef HAVE_KSECRETSSERVICE
820  }
821 #endif
822 }
823 
824 
825 bool Wallet::hasFolder(const QString& f) {
826 #ifdef HAVE_KSECRETSSERVICE
827  if (walletLauncher->m_useKSecretsService) {
828  // FIXME: well, this is not the best implementation, but it's done quickly :)
829  // the best way would be to searchItems with the attribute label having the value f
830  // doing that would reduce DBus traffic. But KWallet API wille not last.
831  QStringList folders = folderList();
832  return folders.contains(f);
833  }
834  else {
835 #endif
836  if (d->handle == -1) {
837  return false;
838  }
839 
840  QDBusReply<bool> r = walletLauncher->getInterface().hasFolder(d->handle, f, appid());
841  if (!r.isValid())
842  {
843  kDebug(285) << "Invalid DBus reply: " << r.error();
844  return false;
845  }
846  else
847  return r;
848 #ifdef HAVE_KSECRETSSERVICE
849  }
850 #endif
851 }
852 
853 
854 bool Wallet::createFolder(const QString& f) {
855 #ifdef HAVE_KSECRETSSERVICE
856  if (walletLauncher->m_useKSecretsService) {
857  QString strDummy("");
858  d->folder = f;
859  d->writeEntry( f, strDummy, KWallet::Wallet::Unknown );
860  return true;
861  }
862  else {
863 #endif
864  if (d->handle == -1) {
865  return false;
866  }
867 
868  if (!hasFolder(f)) {
869  QDBusReply<bool> r = walletLauncher->getInterface().createFolder(d->handle, f, appid());
870 
871  if (!r.isValid())
872  {
873  kDebug(285) << "Invalid DBus reply: " << r.error();
874  return false;
875  }
876  else
877  return r;
878  }
879 
880  return true; // folder already exists
881 #ifdef HAVE_KSECRETSSERVICE
882  }
883 #endif
884 }
885 
886 
887 bool Wallet::setFolder(const QString& f) {
888  bool rc = false;
889 
890 #ifdef HAVE_KSECRETSSERVICE
891  if (walletLauncher->m_useKSecretsService) {
892  if (hasFolder(f)) {
893  d->folder = f;
894  rc = true;
895  }
896  }
897  else {
898 #endif
899  if (d->handle == -1) {
900  return rc;
901  }
902 
903  // Don't do this - the folder could have disappeared?
904  #if 0
905  if (f == d->folder) {
906  return true;
907  }
908  #endif
909 
910  if (hasFolder(f)) {
911  d->folder = f;
912  rc = true;
913  }
914 #ifdef HAVE_KSECRETSSERVICE
915  }
916 #endif
917 
918  return rc;
919 }
920 
921 
922 bool Wallet::removeFolder(const QString& f) {
923 #ifdef HAVE_KSECRETSSERVICE
924  if (walletLauncher->m_useKSecretsService) {
925  bool result = false;
926  // search for all items having the folder f then delete them
927  KSecretsService::StringStringMap attrs;
928  attrs[KSS_ATTR_ENTRYFOLDER] = f;
929  KSecretsService::SearchCollectionItemsJob *searchJob = d->secretsCollection->searchItems(attrs);
930  if (searchJob->exec()) {
931  KSecretsService::SearchCollectionItemsJob::ItemList itemList = searchJob->items();
932  if ( !itemList.isEmpty() ) {
933  result = true;
934  foreach( const KSecretsService::SearchCollectionItemsJob::Item &item, itemList ) {
935  KSecretsService::SecretItemDeleteJob *deleteJob = item->deleteItem();
936  if (!deleteJob->exec()) {
937  kDebug(285) << "Cannot delete item : " << deleteJob->errorString();
938  result = false;
939  }
940  result &= true;
941  }
942  }
943  }
944  else {
945  kDebug(285) << "Cannot execute KSecretsService::SearchCollectionItemsJob : " << searchJob->errorString();
946  }
947  return result;
948  }
949  else {
950 #endif
951  if (d->handle == -1) {
952  return false;
953  }
954 
955  QDBusReply<bool> r = walletLauncher->getInterface().removeFolder(d->handle, f, appid());
956  if (d->folder == f) {
957  setFolder(QString());
958  }
959 
960  if (!r.isValid())
961  {
962  kDebug(285) << "Invalid DBus reply: " << r.error();
963  return false;
964  }
965  else
966  return r;
967 #ifdef HAVE_KSECRETSSERVICE
968  }
969 #endif
970 }
971 
972 
973 const QString& Wallet::currentFolder() const {
974  return d->folder;
975 }
976 
977 #ifdef HAVE_KSECRETSSERVICE
978 QExplicitlySharedDataPointer<KSecretsService::SecretItem> Wallet::WalletPrivate::findItem( const QString& key ) const
979 {
980  QExplicitlySharedDataPointer<KSecretsService::SecretItem> result;
981  KSecretsService::StringStringMap attrs;
982  attrs[KSS_ATTR_ENTRYFOLDER] = folder;
983  attrs["Label"] = key;
984  KSecretsService::SearchCollectionItemsJob *searchJob = secretsCollection->searchItems(attrs);
985  if (searchJob->exec()) {
986  KSecretsService::SearchCollectionItemsJob::ItemList itemList = searchJob->items();
987  if ( !itemList.isEmpty() ) {
988  result = itemList.first();
989  }
990  else {
991  kDebug(285) << "entry named " << key << " not found in folder " << folder;
992  }
993  }
994  else {
995  kDebug(285) << "Cannot exec KSecretsService::SearchCollectionItemsJob : " << searchJob->errorString();
996  }
997 
998  return result;
999 }
1000 
1001 template <typename T>
1002 int Wallet::WalletPrivate::readEntry(const QString& key, T& value) const
1003 {
1004  int rc = -1;
1005  QExplicitlySharedDataPointer<KSecretsService::SecretItem> item = findItem(key);
1006  if ( item ) {
1007  KSecretsService::GetSecretItemSecretJob *readJob = item->getSecret();
1008  if ( readJob->exec() ) {
1009  KSecretsService::Secret theSecret = readJob->secret();
1010  kDebug(285) << "Secret contentType is " << theSecret.contentType();
1011  value = theSecret.value().value<T>();
1012  rc = 0;
1013  }
1014  else {
1015  kDebug(285) << "Cannot exec GetSecretItemSecretJob : " << readJob->errorString();
1016  }
1017  }
1018  return rc;
1019 }
1020 
1021 bool Wallet::WalletPrivate::readSecret(const QString& key, KSecretsService::Secret& value) const
1022 {
1023  bool result = false;
1024  QExplicitlySharedDataPointer<KSecretsService::SecretItem> item = findItem(key);
1025  if ( item ) {
1026  KSecretsService::GetSecretItemSecretJob *readJob = item->getSecret();
1027  if ( readJob->exec() ) {
1028  value = readJob->secret();
1029  result = true;
1030  }
1031  else {
1032  kDebug(285) << "Cannot exec GetSecretItemSecretJob : " << readJob->errorString();
1033  }
1034  }
1035  return result;
1036 }
1037 #endif
1038 
1039 int Wallet::readEntry(const QString& key, QByteArray& value) {
1040  int rc = -1;
1041 
1042 #ifdef HAVE_KSECRETSSERVICE
1043  if (walletLauncher->m_useKSecretsService) {
1044  return d->readEntry<QByteArray>(key, value);
1045  }
1046  else {
1047 #endif
1048  if (d->handle == -1) {
1049  return rc;
1050  }
1051 
1052  QDBusReply<QByteArray> r = walletLauncher->getInterface().readEntry(d->handle, d->folder, key, appid());
1053  if (r.isValid()) {
1054  value = r;
1055  rc = 0;
1056  }
1057 #ifdef HAVE_KSECRETSSERVICE
1058  }
1059 #endif
1060 
1061  return rc;
1062 }
1063 
1064 #ifdef HAVE_KSECRETSSERVICE
1065 struct Wallet::WalletPrivate::InsertIntoEntryList {
1066  InsertIntoEntryList( QMap< QString, QByteArray> &value ) : _value( value ) {}
1067  bool operator() ( Wallet::WalletPrivate*, const QString& label, KSecretsService::SecretItem* item ) {
1068  bool result = false;
1069  KSecretsService::GetSecretItemSecretJob *readSecretJob = item->getSecret();
1070  if ( readSecretJob->exec() ) {
1071  _value.insert( label, readSecretJob->secret().value().toByteArray() );
1072  result = true;
1073  }
1074  else {
1075  kDebug(285) << "Cannot execute GetSecretItemSecretJob " << readSecretJob->errorString();
1076  }
1077  return result;
1078  }
1079  QMap< QString, QByteArray > _value;
1080 };
1081 #endif
1082 
1083 int Wallet::readEntryList(const QString& key, QMap<QString, QByteArray>& value) {
1084 
1085  int rc = -1;
1086 
1087 #ifdef HAVE_KSECRETSSERVICE
1088  if (walletLauncher->m_useKSecretsService) {
1089  rc = d->forEachItemThatMatches( key, WalletPrivate::InsertIntoEntryList( value ) );
1090  }
1091  else {
1092 #endif
1093  registerTypes();
1094 
1095  if (d->handle == -1) {
1096  return rc;
1097  }
1098 
1099  QDBusReply<QVariantMap> r = walletLauncher->getInterface().readEntryList(d->handle, d->folder, key, appid());
1100  if (r.isValid()) {
1101  rc = 0;
1102  // convert <QString, QVariant> to <QString, QByteArray>
1103  const QVariantMap val = r.value();
1104  for( QVariantMap::const_iterator it = val.begin(); it != val.end(); ++it ) {
1105  value.insert(it.key(), it.value().toByteArray());
1106  }
1107  }
1108 #ifdef HAVE_KSECRETSSERVICE
1109  }
1110 #endif
1111 
1112  return rc;
1113 }
1114 
1115 
1116 int Wallet::renameEntry(const QString& oldName, const QString& newName) {
1117  int rc = -1;
1118 
1119 #ifdef HAVE_KSECRETSSERVICE
1120  if (walletLauncher->m_useKSecretsService) {
1121  QExplicitlySharedDataPointer<KSecretsService::SecretItem> item = d->findItem(oldName);
1122  if (item) {
1123  KSecretsService::WriteItemPropertyJob *writeJob = item->setLabel(newName);
1124  if (!writeJob->exec()) {
1125  kDebug(285) << "Cannot exec WriteItemPropertyJob : " << writeJob->errorString();
1126  }
1127  rc = writeJob->error();
1128  }
1129  else {
1130  kDebug(285) << "Cannot locate item " << oldName << " in folder " << d->folder;
1131  }
1132  }
1133  else {
1134 #endif
1135  if (d->handle == -1) {
1136  return rc;
1137  }
1138 
1139  QDBusReply<int> r = walletLauncher->getInterface().renameEntry(d->handle, d->folder, oldName, newName, appid());
1140  if (r.isValid()) {
1141  rc = r;
1142  }
1143 #ifdef HAVE_KSECRETSSERVICE
1144  }
1145 #endif
1146 
1147  return rc;
1148 }
1149 
1150 
1151 int Wallet::readMap(const QString& key, QMap<QString,QString>& value) {
1152  int rc = -1;
1153 
1154 #ifdef HAVE_KSECRETSSERVICE
1155  if (walletLauncher->m_useKSecretsService) {
1156  QByteArray ba;
1157  rc = d->readEntry< QByteArray >(key, ba);
1158  if ( rc == 0 && !ba.isEmpty()){
1159  QDataStream ds( &ba, QIODevice::ReadOnly );
1160  ds >> value;
1161  }
1162  }
1163  else {
1164 #endif
1165  registerTypes();
1166 
1167  if (d->handle == -1) {
1168  return rc;
1169  }
1170 
1171  QDBusReply<QByteArray> r = walletLauncher->getInterface().readMap(d->handle, d->folder, key, appid());
1172  if (r.isValid()) {
1173  rc = 0;
1174  QByteArray v = r;
1175  if (!v.isEmpty()) {
1176  QDataStream ds(&v, QIODevice::ReadOnly);
1177  ds >> value;
1178  }
1179  }
1180 #ifdef HAVE_KSECRETSSERVICE
1181  }
1182 #endif
1183 
1184  return rc;
1185 }
1186 
1187 #ifdef HAVE_KSECRETSSERVICE
1188 struct Wallet::WalletPrivate::InsertIntoMapList {
1189  InsertIntoMapList( QMap< QString, QMap< QString, QString > > &value ) : _value( value ) {}
1190  bool operator() ( Wallet::WalletPrivate* d, const QString& label, KSecretsService::SecretItem* ) {
1191  bool result = false;
1192  QMap<QString, QString> map;
1193  if ( d->readEntry< QMap< QString, QString> >(label, map) ) {
1194  _value.insert( label, map );
1195  result = true;
1196  }
1197  return result;
1198  }
1199  QMap< QString, QMap< QString, QString> > &_value;
1200 };
1201 #endif
1202 
1203 int Wallet::readMapList(const QString& key, QMap<QString, QMap<QString, QString> >& value) {
1204  int rc = -1;
1205 
1206 #ifdef HAVE_KSECRETSSERVICE
1207  if (walletLauncher->m_useKSecretsService) {
1208  rc = d->forEachItemThatMatches( key, WalletPrivate::InsertIntoMapList( value ) );
1209  }
1210  else {
1211 #endif
1212  registerTypes();
1213 
1214  if (d->handle == -1) {
1215  return rc;
1216  }
1217 
1218  QDBusReply<QVariantMap> r =
1219  walletLauncher->getInterface().readMapList(d->handle, d->folder, key, appid());
1220  if (r.isValid()) {
1221  rc = 0;
1222  const QVariantMap val = r.value();
1223  for( QVariantMap::const_iterator it = val.begin(); it != val.end(); ++it ) {
1224  QByteArray mapData = it.value().toByteArray();
1225  if (!mapData.isEmpty()) {
1226  QDataStream ds(&mapData, QIODevice::ReadOnly);
1227  QMap<QString,QString> v;
1228  ds >> v;
1229  value.insert(it.key(), v);
1230  }
1231  }
1232  }
1233 #ifdef HAVE_KSECRETSSERVICE
1234  }
1235 #endif
1236 
1237  return rc;
1238 }
1239 
1240 
1241 int Wallet::readPassword(const QString& key, QString& value) {
1242  int rc = -1;
1243 
1244 #ifdef HAVE_KSECRETSSERVICE
1245  if (walletLauncher->m_useKSecretsService) {
1246  rc = d->readEntry<QString>(key, value);
1247  }
1248  else {
1249 #endif
1250  if (d->handle == -1) {
1251  return rc;
1252  }
1253 
1254  QDBusReply<QString> r = walletLauncher->getInterface().readPassword(d->handle, d->folder, key, appid());
1255  if (r.isValid()) {
1256  value = r;
1257  rc = 0;
1258  }
1259 #ifdef HAVE_KSECRETSSERVICE
1260  }
1261 #endif
1262 
1263  return rc;
1264 }
1265 
1266 #ifdef HAVE_KSECRETSSERVICE
1267 struct Wallet::WalletPrivate::InsertIntoPasswordList {
1268  InsertIntoPasswordList( QMap< QString, QString> &value ) : _value( value ) {}
1269  bool operator() ( Wallet::WalletPrivate* d, const QString& label, KSecretsService::SecretItem* ) {
1270  bool result = false;
1271  QString pwd;
1272  if ( d->readEntry<QString>( label, pwd ) == 0 ) {
1273  _value.insert( label, pwd );
1274  result = true;
1275  }
1276  return result;
1277  }
1278  QMap< QString, QString > &_value;
1279 };
1280 #endif
1281 
1282 int Wallet::readPasswordList(const QString& key, QMap<QString, QString>& value) {
1283  int rc = -1;
1284 
1285 #ifdef HAVE_KSECRETSSERVICE
1286  if (walletLauncher->m_useKSecretsService) {
1287  rc = d->forEachItemThatMatches( key, WalletPrivate::InsertIntoPasswordList( value ) );
1288  }
1289  else {
1290 #endif
1291  registerTypes();
1292 
1293  if (d->handle == -1) {
1294  return rc;
1295  }
1296 
1297  QDBusReply<QVariantMap> r = walletLauncher->getInterface().readPasswordList(d->handle, d->folder, key, appid());
1298  if (r.isValid()) {
1299  rc = 0;
1300  const QVariantMap val = r.value();
1301  for( QVariantMap::const_iterator it = val.begin(); it != val.end(); ++it ) {
1302  value.insert(it.key(), it.value().toString());
1303  }
1304  }
1305 #ifdef HAVE_KSECRETSSERVICE
1306  }
1307 #endif
1308 
1309  return rc;
1310 }
1311 
1312 
1313 int Wallet::writeEntry(const QString& key, const QByteArray& value, EntryType entryType) {
1314  int rc = -1;
1315 
1316 #ifdef HAVE_KSECRETSSERVICE
1317  if (walletLauncher->m_useKSecretsService) {
1318  rc = d->writeEntry( key, value, entryType );
1319  }
1320  else {
1321 #endif
1322  if (d->handle == -1) {
1323  return rc;
1324  }
1325 
1326  QDBusReply<int> r = walletLauncher->getInterface().writeEntry(d->handle, d->folder, key, value, int(entryType), appid());
1327  if (r.isValid()) {
1328  rc = r;
1329  }
1330 #ifdef HAVE_KSECRETSSERVICE
1331  }
1332 #endif
1333 
1334  return rc;
1335 }
1336 
1337 
1338 int Wallet::writeEntry(const QString& key, const QByteArray& value) {
1339  int rc = -1;
1340 
1341 #ifdef HAVE_KSECRETSSERVICE
1342  if (walletLauncher->m_useKSecretsService) {
1343  rc = writeEntry( key, value, Stream );
1344  }
1345  else {
1346 #endif
1347  if (d->handle == -1) {
1348  return rc;
1349  }
1350 
1351  QDBusReply<int> r = walletLauncher->getInterface().writeEntry(d->handle, d->folder, key, value, appid());
1352  if (r.isValid()) {
1353  rc = r;
1354  }
1355 #ifdef HAVE_KSECRETSSERVICE
1356  }
1357 #endif
1358 
1359  return rc;
1360 }
1361 
1362 
1363 int Wallet::writeMap(const QString& key, const QMap<QString,QString>& value) {
1364  int rc = -1;
1365 
1366 #ifdef HAVE_KSECRETSSERVICE
1367  if (walletLauncher->m_useKSecretsService) {
1368  d->writeEntry( key, value, Map );
1369  }
1370  else {
1371 #endif
1372  registerTypes();
1373 
1374  if (d->handle == -1) {
1375  return rc;
1376  }
1377 
1378  QByteArray mapData;
1379  QDataStream ds(&mapData, QIODevice::WriteOnly);
1380  ds << value;
1381  QDBusReply<int> r = walletLauncher->getInterface().writeMap(d->handle, d->folder, key, mapData, appid());
1382  if (r.isValid()) {
1383  rc = r;
1384  }
1385 #ifdef HAVE_KSECRETSSERVICE
1386  }
1387 #endif
1388 
1389  return rc;
1390 }
1391 
1392 
1393 int Wallet::writePassword(const QString& key, const QString& value) {
1394  int rc = -1;
1395 
1396 #ifdef HAVE_KSECRETSSERVICE
1397  if (walletLauncher->m_useKSecretsService) {
1398  rc = d->writeEntry( key, value, Password );
1399  }
1400  else {
1401 #endif
1402  if (d->handle == -1) {
1403  return rc;
1404  }
1405 
1406  QDBusReply<int> r = walletLauncher->getInterface().writePassword(d->handle, d->folder, key, value, appid());
1407  if (r.isValid()) {
1408  rc = r;
1409  }
1410 #ifdef HAVE_KSECRETSSERVICE
1411  }
1412 #endif
1413 
1414  return rc;
1415 }
1416 
1417 
1418 bool Wallet::hasEntry(const QString& key) {
1419 #ifdef HAVE_KSECRETSSERVICE
1420  if (walletLauncher->m_useKSecretsService) {
1421  QExplicitlySharedDataPointer<KSecretsService::SecretItem> item = d->findItem( key );
1422  return item;
1423  }
1424  else {
1425 #endif
1426  if (d->handle == -1) {
1427  return false;
1428  }
1429 
1430  QDBusReply<bool> r = walletLauncher->getInterface().hasEntry(d->handle, d->folder, key, appid());
1431  if (!r.isValid())
1432  {
1433  kDebug(285) << "Invalid DBus reply: " << r.error();
1434  return false;
1435  }
1436  else
1437  return r;
1438 #ifdef HAVE_KSECRETSSERVICE
1439  }
1440 #endif
1441 }
1442 
1443 
1444 int Wallet::removeEntry(const QString& key) {
1445  int rc = -1;
1446 
1447 #ifdef HAVE_KSECRETSSERVICE
1448  if (walletLauncher->m_useKSecretsService) {
1449  QExplicitlySharedDataPointer<KSecretsService::SecretItem> item = d->findItem( key );
1450  if ( item ) {
1451  KSecretsService::SecretItemDeleteJob *deleteJob = item->deleteItem();
1452  if ( !deleteJob->exec() ) {
1453  kDebug(285) << "Cannot execute SecretItemDeleteJob " << deleteJob->errorString();
1454  }
1455  rc = deleteJob->error();
1456  }
1457  }
1458  else {
1459 #endif
1460  if (d->handle == -1) {
1461  return rc;
1462  }
1463 
1464  QDBusReply<int> r = walletLauncher->getInterface().removeEntry(d->handle, d->folder, key, appid());
1465  if (r.isValid()) {
1466  rc = r;
1467  }
1468 #ifdef HAVE_KSECRETSSERVICE
1469  }
1470 #endif
1471 
1472  return rc;
1473 }
1474 
1475 
1476 Wallet::EntryType Wallet::entryType(const QString& key) {
1477  int rc = 0;
1478 
1479 #ifdef HAVE_KSECRETSSERVICE
1480  if (walletLauncher->m_useKSecretsService) {
1481  QExplicitlySharedDataPointer<KSecretsService::SecretItem> item = d->findItem( key );
1482  if ( item ) {
1483  KSecretsService::ReadItemPropertyJob *readAttrsJob = item->attributes();
1484  if ( readAttrsJob->exec() ) {
1485  KSecretsService::StringStringMap attrs = readAttrsJob->propertyValue().value<KSecretsService::StringStringMap>();
1486  if ( attrs.contains( KSS_ATTR_WALLETTYPE ) ) {
1487  QString entryType = attrs[KSS_ATTR_WALLETTYPE];
1488  bool ok = false;
1489  rc = entryType.toInt( &ok );
1490  if ( !ok ) {
1491  rc = 0;
1492  kDebug(285) << KSS_ATTR_WALLETTYPE << " attribute holds non int value " << attrs[KSS_ATTR_WALLETTYPE];
1493  }
1494  }
1495  }
1496  else {
1497  kDebug(285) << "Cannot execute GetSecretItemSecretJob " << readAttrsJob->errorString();
1498  }
1499  }
1500  }
1501  else {
1502 #endif
1503  if (d->handle == -1) {
1504  return Wallet::Unknown;
1505  }
1506 
1507  QDBusReply<int> r = walletLauncher->getInterface().entryType(d->handle, d->folder, key, appid());
1508  if (r.isValid()) {
1509  rc = r;
1510  }
1511 #ifdef HAVE_KSECRETSSERVICE
1512  }
1513 #endif
1514  return static_cast<EntryType>(rc);
1515 }
1516 
1517 
1518 void Wallet::WalletPrivate::walletServiceUnregistered()
1519 {
1520  if (loop) {
1521  loop->quit();
1522  }
1523 
1524  if (handle >= 0) {
1525  q->slotWalletClosed(handle);
1526  }
1527 }
1528 
1529 void Wallet::slotFolderUpdated(const QString& wallet, const QString& folder) {
1530 #ifdef HAVE_KSECRETSSERVICE
1531  if (walletLauncher->m_useKSecretsService) {
1532  // TODO: implement this
1533  Q_ASSERT(0);
1534  }
1535  else {
1536 #endif
1537  if (d->name == wallet) {
1538  emit folderUpdated(folder);
1539  }
1540 #ifdef HAVE_KSECRETSSERVICE
1541  }
1542 #endif
1543 }
1544 
1545 
1546 void Wallet::slotFolderListUpdated(const QString& wallet) {
1547 #ifdef HAVE_KSECRETSSERVICE
1548  if (walletLauncher->m_useKSecretsService) {
1549  // TODO: implement this
1550  Q_ASSERT(0);
1551  }
1552  else {
1553 #endif
1554  if (d->name == wallet) {
1555  emit folderListUpdated();
1556  }
1557 #ifdef HAVE_KSECRETSSERVICE
1558  }
1559 #endif
1560 }
1561 
1562 
1563 void Wallet::slotApplicationDisconnected(const QString& wallet, const QString& application) {
1564 #ifdef HAVE_KSECRETSSERVICE
1565  if (walletLauncher->m_useKSecretsService) {
1566  // TODO: implement this
1567  Q_ASSERT(0);
1568  }
1569  else {
1570 #endif
1571  if (d->handle >= 0
1572  && d->name == wallet
1573  && application == appid()) {
1574  slotWalletClosed(d->handle);
1575  }
1576 #ifdef HAVE_KSECRETSSERVICE
1577  }
1578 #endif
1579 }
1580 
1581 void Wallet::walletAsyncOpened(int tId, int handle) {
1582 #ifdef HAVE_KSECRETSSERVICE
1583  if (walletLauncher->m_useKSecretsService) {
1584  // TODO: implement this
1585  Q_ASSERT(0);
1586  }
1587  else {
1588 #endif
1589  // ignore responses to calls other than ours
1590  if (d->transactionId != tId || d->handle != -1) {
1591  return;
1592  }
1593 
1594  // disconnect the async signal
1595  disconnect(this, SLOT(walletAsyncOpened(int,int)));
1596 
1597  d->handle = handle;
1598  emit walletOpened(handle > 0);
1599 #ifdef HAVE_KSECRETSSERVICE
1600  }
1601 #endif
1602 }
1603 
1604 void Wallet::emitWalletAsyncOpenError() {
1605  emit walletOpened(false);
1606 }
1607 
1608 void Wallet::emitWalletOpened() {
1609  emit walletOpened(true);
1610 }
1611 
1612 bool Wallet::folderDoesNotExist(const QString& wallet, const QString& folder)
1613 {
1614 #ifdef HAVE_KSECRETSSERVICE
1615  if (walletLauncher->m_useKSecretsService) {
1616  kDebug(285) << "WARNING: changing semantics of folderDoesNotExist with KSS: will prompt for the password";
1617  Wallet *w = openWallet( wallet, 0, Synchronous );
1618  if ( w ) {
1619  return !w->hasFolder( folder );
1620  }
1621  else {
1622  return true;
1623  }
1624  }
1625  else {
1626 #endif
1627  QDBusReply<bool> r = walletLauncher->getInterface().folderDoesNotExist(wallet, folder);
1628  if (!r.isValid())
1629  {
1630  kDebug(285) << "Invalid DBus reply: " << r.error();
1631  return false;
1632  }
1633  else
1634  return r;
1635 #ifdef HAVE_KSECRETSSERVICE
1636  }
1637 #endif
1638 }
1639 
1640 
1641 bool Wallet::keyDoesNotExist(const QString& wallet, const QString& folder, const QString& key)
1642 {
1643 #ifdef HAVE_KSECRETSSERVICE
1644  if (walletLauncher->m_useKSecretsService) {
1645  kDebug(285) << "WARNING: changing semantics of keyDoesNotExist with KSS: will prompt for the password";
1646  Wallet *w = openWallet( wallet, 0, Synchronous );
1647  if ( w ) {
1648  return !w->hasEntry(key);
1649  }
1650  return false;
1651  }
1652  else {
1653 #endif
1654  QDBusReply<bool> r = walletLauncher->getInterface().keyDoesNotExist(wallet, folder, key);
1655  if (!r.isValid())
1656  {
1657  kDebug(285) << "Invalid DBus reply: " << r.error();
1658  return false;
1659  }
1660  else
1661  return r;
1662 #ifdef HAVE_KSECRETSSERVICE
1663  }
1664 #endif
1665 }
1666 
1667 void Wallet::virtual_hook(int, void*) {
1668  //BASE::virtual_hook( id, data );
1669 }
1670 
1671 
1672 KWalletDLauncher::KWalletDLauncher()
1673  : m_wallet(0),
1674  m_cgroup(KSharedConfig::openConfig("kwalletrc", KConfig::NoGlobals)->group("Wallet"))
1675 {
1676  m_useKSecretsService = m_cgroup.readEntry("UseKSecretsService", false);
1677 #ifdef HAVE_KSECRETSSERVICE
1678  if (m_useKSecretsService) {
1679  // NOOP
1680  }
1681  else {
1682 #endif
1683  m_wallet = new org::kde::KWallet(QString::fromLatin1(s_kwalletdServiceName), "/modules/kwalletd", QDBusConnection::sessionBus());
1684 #ifdef HAVE_KSECRETSSERVICE
1685  }
1686 #endif
1687 }
1688 
1689 KWalletDLauncher::~KWalletDLauncher()
1690 {
1691  delete m_wallet;
1692 }
1693 
1694 org::kde::KWallet &KWalletDLauncher::getInterface()
1695 {
1696 // Q_ASSERT(!m_useKSecretsService);
1697  Q_ASSERT(m_wallet != 0);
1698 
1699  // check if kwalletd is already running
1700  if (!QDBusConnection::sessionBus().interface()->isServiceRegistered(QString::fromLatin1(s_kwalletdServiceName)))
1701  {
1702  // not running! check if it is enabled.
1703  bool walletEnabled = m_cgroup.readEntry("Enabled", true);
1704  if (walletEnabled) {
1705  // wallet is enabled! try launching it
1706  QString error;
1707  int ret = KToolInvocation::startServiceByDesktopPath("kwalletd.desktop", QStringList(), &error);
1708  if (ret > 0)
1709  {
1710  kError(285) << "Couldn't start kwalletd: " << error << endl;
1711  }
1712 
1713  if
1714  (!QDBusConnection::sessionBus().interface()->isServiceRegistered(QString::fromLatin1(s_kwalletdServiceName))) {
1715  kDebug(285) << "The kwalletd service is still not registered";
1716  } else {
1717  kDebug(285) << "The kwalletd service has been registered";
1718  }
1719  } else {
1720  kError(285) << "The kwalletd service has been disabled";
1721  }
1722  }
1723 
1724  return *m_wallet;
1725 }
1726 
1727 } // namespace KWallet
1728 
1729 #include "kwallet.moc"
This file is part of the KDE documentation.
Documentation copyright © 1996-2013 The KDE developers.
Generated on Tue Jul 16 2013 17:49:42 by doxygen 1.8.1.1 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDEUI

Skip menu "KDEUI"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs-4.10.5 API Reference

Skip menu "kdelibs-4.10.5 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal