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

KDEUI

  • sources
  • kde-4.14
  • kdelibs
  • 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 };
225 
226 #ifdef HAVE_KSECRETSSERVICE
227 void Wallet::WalletPrivate::createDefaultFolders()
228 {
229 // NOTE: KWalletManager expects newly created wallets to have two default folders
230 // b->createFolder(KWallet::Wallet::PasswordFolder());
231 // b->createFolder(KWallet::Wallet::FormDataFolder());
232  QString strDummy("");
233  folder = PasswordFolder();
234  writeEntry( PasswordFolder(), strDummy, KWallet::Wallet::Unknown );
235 
236  folder = FormDataFolder();
237  writeEntry( FormDataFolder(), strDummy, KWallet::Wallet::Unknown );
238 }
239 #endif // HAVE_KSECRETSSERVICE
240 
241 static const char s_kwalletdServiceName[] = "org.kde.kwalletd";
242 
243 Wallet::Wallet(int handle, const QString& name)
244  : QObject(0L), d(new WalletPrivate(this, handle, name))
245 {
246  if (walletLauncher->m_useKSecretsService) {
247  // see openWallet for initialization code; this constructor does not have any code
248  }
249  else {
250  QDBusServiceWatcher *watcher = new QDBusServiceWatcher(QString::fromLatin1(s_kwalletdServiceName), QDBusConnection::sessionBus(),
251  QDBusServiceWatcher::WatchForUnregistration, this);
252  connect(watcher, SIGNAL(serviceUnregistered(QString)),
253  this, SLOT(walletServiceUnregistered()));
254 
255  connect(&walletLauncher->getInterface(), SIGNAL(walletClosed(int)), SLOT(slotWalletClosed(int)));
256  connect(&walletLauncher->getInterface(), SIGNAL(folderListUpdated(QString)), SLOT(slotFolderListUpdated(QString)));
257  connect(&walletLauncher->getInterface(), SIGNAL(folderUpdated(QString,QString)), SLOT(slotFolderUpdated(QString,QString)));
258  connect(&walletLauncher->getInterface(), SIGNAL(applicationDisconnected(QString,QString)), SLOT(slotApplicationDisconnected(QString,QString)));
259 
260  // Verify that the wallet is still open
261  if (d->handle != -1) {
262  QDBusReply<bool> r = walletLauncher->getInterface().isOpen(d->handle);
263  if (r.isValid() && !r) {
264  d->handle = -1;
265  d->name.clear();
266  }
267  }
268  }
269 }
270 
271 
272 Wallet::~Wallet() {
273 #ifdef HAVE_KSECRETSSERVICE
274  if (walletLauncher->m_useKSecretsService) {
275  d->folder.clear();
276  d->name.clear();
277  delete d->secretsCollection;
278  }
279  else {
280 #endif
281  if (d->handle != -1) {
282  if (!walletLauncher.isDestroyed()) {
283  walletLauncher->getInterface().close(d->handle, false, appid());
284  } else {
285  kDebug(285) << "Problem with static destruction sequence."
286  "Destroy any static Wallet before the event-loop exits.";
287  }
288  d->handle = -1;
289  d->folder.clear();
290  d->name.clear();
291  }
292 #ifdef HAVE_KSECRETSSERVICE
293  }
294 #endif
295  delete d;
296 }
297 
298 
299 QStringList Wallet::walletList() {
300  QStringList result;
301 #ifdef HAVE_KSECRETSSERVICE
302  if (walletLauncher->m_useKSecretsService) {
303  KSecretsService::ListCollectionsJob *listJob = KSecretsService::Collection::listCollections();
304  if ( listJob->exec() ) {
305  result = listJob->collections();
306  }
307  else {
308  kDebug(285) << "Cannot execute ListCollectionsJob: " << listJob->errorString();
309  }
310  }
311  else {
312 #endif
313  QDBusReply<QStringList> r = walletLauncher->getInterface().wallets();
314 
315  if (!r.isValid())
316  {
317  kDebug(285) << "Invalid DBus reply: " << r.error();
318  }
319  else
320  result = r;
321 #ifdef HAVE_KSECRETSSERVICE
322  }
323 #endif
324  return result;
325 }
326 
327 
328 void Wallet::changePassword(const QString& name, WId w) {
329  if( w == 0 )
330  kDebug(285) << "Pass a valid window to KWallet::Wallet::changePassword().";
331 
332  // Make sure the password prompt window will be visible and activated
333  KWindowSystem::allowExternalProcessWindowActivation();
334 #ifdef HAVE_KSECRETSSERVICE
335  if (walletLauncher->m_useKSecretsService) {
336  KSecretsService::Collection *coll = KSecretsService::Collection::findCollection( name );
337  KSecretsService::ChangeCollectionPasswordJob* changePwdJob = coll->changePassword();
338  if ( !changePwdJob->exec() ) {
339  kDebug(285) << "Cannot execute change password job: " << changePwdJob->errorString();
340  }
341  coll->deleteLater();
342  }
343  else {
344 #endif
345  walletLauncher->getInterface().changePassword(name, (qlonglong)w, appid());
346 #ifdef HAVE_KSECRETSSERVICE
347  }
348 #endif
349 }
350 
351 
352 bool Wallet::isEnabled() {
353 #ifdef HAVE_KSECRETSSERVICE
354  if (walletLauncher->m_useKSecretsService) {
355  return walletLauncher->m_cgroup.readEntry("Enabled", true);
356  }
357  else {
358 #endif
359  QDBusReply<bool> r = walletLauncher->getInterface().isEnabled();
360 
361  if (!r.isValid())
362  {
363  kDebug(285) << "Invalid DBus reply: " << r.error();
364  return false;
365  }
366  else
367  return r;
368 #ifdef HAVE_KSECRETSSERVICE
369  }
370 #endif
371 }
372 
373 
374 bool Wallet::isOpen(const QString& name) {
375 #ifdef HAVE_KSECRETSSERVICE
376  if (walletLauncher->m_useKSecretsService) {
377  KSecretsService::Collection *coll = KSecretsService::Collection::findCollection( name, KSecretsService::Collection::OpenOnly );
378  KSecretsService::ReadCollectionPropertyJob *readLocked = coll->isLocked();
379  if ( readLocked->exec() ) {
380  return !readLocked->propertyValue().toBool();
381  }
382  else {
383  kDebug() << "ReadLocked job failed";
384  return false;
385  }
386  }
387  else {
388 #endif
389  QDBusReply<bool> r = walletLauncher->getInterface().isOpen(name);
390 
391  if (!r.isValid())
392  {
393  kDebug(285) << "Invalid DBus reply: " << r.error();
394  return false;
395  }
396  else
397  return r;
398 #ifdef HAVE_KSECRETSSERVICE
399  }
400 #endif
401 }
402 
403 int Wallet::closeWallet(const QString& name, bool force) {
404 #ifdef HAVE_KSECRETSSERVICE
405  if (walletLauncher->m_useKSecretsService) {
406  kDebug(285) << "Wallet::closeWallet NOOP";
407  return 0;
408  }
409  else {
410 #endif
411  QDBusReply<int> r = walletLauncher->getInterface().close(name, force);
412 
413  if (!r.isValid())
414  {
415  kDebug(285) << "Invalid DBus reply: " << r.error();
416  return -1;
417  }
418  else
419  return r;
420 #ifdef HAVE_KSECRETSSERVICE
421  }
422 #endif
423 }
424 
425 
426 int Wallet::deleteWallet(const QString& name) {
427 #ifdef HAVE_KSECRETSSERVICE
428  if (walletLauncher->m_useKSecretsService) {
429  KSecretsService::Collection *coll = KSecretsService::Collection::findCollection(name, KSecretsService::Collection::OpenOnly);
430  KJob *deleteJob = coll->deleteCollection();
431  if (!deleteJob->exec()) {
432  kDebug(285) << "Cannot execute delete job " << deleteJob->errorString();
433  }
434  return deleteJob->error();
435  }
436  else {
437 #endif
438  QDBusReply<int> r = walletLauncher->getInterface().deleteWallet(name);
439 
440  if (!r.isValid())
441  {
442  kDebug(285) << "Invalid DBus reply: " << r.error();
443  return -1;
444  }
445  else
446  return r;
447 #ifdef HAVE_KSECRETSSERVICE
448  }
449 #endif
450 }
451 
452 Wallet *Wallet::openWallet(const QString& name, WId w, OpenType ot) {
453  if( w == 0 )
454  kDebug(285) << "Pass a valid window to KWallet::Wallet::openWallet().";
455 
456 #ifdef HAVE_KSECRETSSERVICE
457  if (walletLauncher->m_useKSecretsService) {
458  Wallet *wallet = new Wallet(-1, name);
459  // FIXME: should we specify CreateCollection or OpenOnly here?
460  wallet->d->secretsCollection = KSecretsService::Collection::findCollection(name, KSecretsService::Collection::CreateCollection, QVariantMap(), w);
461  connect( wallet->d->secretsCollection, SIGNAL(statusChanged(int)), wallet, SLOT(slotCollectionStatusChanged(int)) );
462  connect( wallet->d->secretsCollection, SIGNAL(deleted()), wallet, SLOT(slotCollectionDeleted()) );
463  if ( ot == Synchronous ) {
464  kDebug() << "WARNING openWallet OpenType=Synchronous requested";
465  // TODO: not sure what to do with in this case; however, all other KSecretsService API methods are already
466  // async and will perform sync inside this API because of it's design
467  }
468  return wallet;
469  }
470  else {
471 #endif
472  Wallet *wallet = new Wallet(-1, name);
473 
474  // connect the daemon's opened signal to the slot filtering the
475  // signals we need
476  connect(&walletLauncher->getInterface(), SIGNAL(walletAsyncOpened(int,int)),
477  wallet, SLOT(walletAsyncOpened(int,int)));
478 
479  // Make sure the password prompt window will be visible and activated
480  KWindowSystem::allowExternalProcessWindowActivation();
481 
482  org::kde::KWallet &interface = walletLauncher->getInterface();
483 
484  // do the call
485  QDBusReply<int> r;
486  if (ot == Synchronous) {
487  interface.setTimeout(0x7FFFFFFF); // Don't timeout after 25s, but 24 days
488  r = interface.open(name, (qlonglong)w, appid());
489  interface.setTimeout(-1); // Back to the default 25s
490  // after this call, r would contain a transaction id >0 if OK or -1 if NOK
491  // if OK, the slot walletAsyncOpened should have been received, but the transaction id
492  // will not match. We'll get that handle from the reply - see below
493  } else if (ot == Asynchronous) {
494  r = interface.openAsync(name, (qlonglong)w, appid(), true);
495  } else if (ot == Path) {
496  r = interface.openPathAsync(name, (qlonglong)w, appid(), true);
497  } else {
498  delete wallet;
499  return 0;
500  }
501  // error communicating with the daemon (maybe not running)
502  if (!r.isValid()) {
503  kDebug(285) << "Invalid DBus reply: " << r.error();
504  delete wallet;
505  return 0;
506  }
507  wallet->d->transactionId = r.value();
508 
509  if (ot == Synchronous || ot == Path) {
510  // check for an immediate error
511  if (wallet->d->transactionId < 0) {
512  delete wallet;
513  wallet = 0;
514  } else {
515  wallet->d->handle = r.value();
516  }
517  } else if (ot == Asynchronous) {
518  if (wallet->d->transactionId < 0) {
519  QTimer::singleShot(0, wallet, SLOT(emitWalletAsyncOpenError()));
520  // client code is responsible for deleting the wallet
521  }
522  }
523 
524  return wallet;
525 #ifdef HAVE_KSECRETSSERVICE
526  }
527 #endif
528 }
529 
530 void Wallet::slotCollectionStatusChanged(int status)
531 {
532 #ifdef HAVE_KSECRETSSERVICE
533  KSecretsService::Collection::Status collStatus = (KSecretsService::Collection::Status)status;
534  switch ( collStatus ) {
535  case KSecretsService::Collection::NewlyCreated:
536  d->createDefaultFolders();
537  // fall through
538  case KSecretsService::Collection::FoundExisting:
539  emitWalletOpened();
540  break;
541  case KSecretsService::Collection::Deleted:
542  case KSecretsService::Collection::Invalid:
543  case KSecretsService::Collection::Pending:
544  // nothing to do
545  break;
546  case KSecretsService::Collection::NotFound:
547  emitWalletAsyncOpenError();
548  break;
549  }
550 #endif
551 }
552 
553 void Wallet::slotCollectionDeleted()
554 {
555  d->folder.clear();
556  d->name.clear();
557  emit walletClosed();
558 }
559 
560 bool Wallet::disconnectApplication(const QString& wallet, const QString& app) {
561 #ifdef HAVE_KSECRETSSERVICE
562  if (walletLauncher->m_useKSecretsService) {
563  kDebug() << "Wallet::disconnectApplication NOOP";
564  return true;
565  }
566  else {
567 #endif
568  QDBusReply<bool> r = walletLauncher->getInterface().disconnectApplication(wallet, app);
569 
570  if (!r.isValid())
571  {
572  kDebug(285) << "Invalid DBus reply: " << r.error();
573  return false;
574  }
575  else
576  return r;
577 #ifdef HAVE_KSECRETSSERVICE
578  }
579 #endif
580 }
581 
582 
583 QStringList Wallet::users(const QString& name) {
584 #ifdef HAVE_KSECRETSSERVICE
585  if (walletLauncher->m_useKSecretsService) {
586  kDebug() << "KSecretsService does not handle users list";
587  return QStringList();
588  }
589  else {
590 #endif
591  QDBusReply<QStringList> r = walletLauncher->getInterface().users(name);
592  if (!r.isValid())
593  {
594  kDebug(285) << "Invalid DBus reply: " << r.error();
595  return QStringList();
596  }
597  else
598  return r;
599 #ifdef HAVE_KSECRETSSERVICE
600  }
601 #endif
602 }
603 
604 
605 int Wallet::sync() {
606 #ifdef HAVE_KSECRETSSERVICE
607  if (walletLauncher->m_useKSecretsService) {
608  // NOOP with KSecretsService
609  }
610  else {
611 #endif
612  if (d->handle == -1) {
613  return -1;
614  }
615 
616  walletLauncher->getInterface().sync(d->handle, appid());
617 #ifdef HAVE_KSECRETSSERVICE
618  }
619 #endif
620  return 0;
621 }
622 
623 
624 int Wallet::lockWallet() {
625 #ifdef HAVE_KSECRETSSERVICE
626  if (walletLauncher->m_useKSecretsService) {
627  KSecretsService::CollectionLockJob *lockJob = d->secretsCollection->lock();
628  if (lockJob->exec()) {
629  d->folder.clear();
630  d->name.clear();
631  }
632  else {
633  kDebug(285) << "Cannot execute KSecretsService::CollectionLockJob : " << lockJob->errorString();
634  return -1;
635  }
636  return lockJob->error();
637  }
638  else {
639 #endif
640  if (d->handle == -1) {
641  return -1;
642  }
643 
644  QDBusReply<int> r = walletLauncher->getInterface().close(d->handle, true, appid());
645  d->handle = -1;
646  d->folder.clear();
647  d->name.clear();
648  if (r.isValid()) {
649  return r;
650  }
651  else {
652  kDebug(285) << "Invalid DBus reply: " << r.error();
653  return -1;
654  }
655 #ifdef HAVE_KSECRETSSERVICE
656  }
657 #endif
658 }
659 
660 
661 const QString& Wallet::walletName() const {
662  return d->name;
663 }
664 
665 
666 bool Wallet::isOpen() const {
667 #ifdef HAVE_KSECRETSSERVICE
668  if (walletLauncher->m_useKSecretsService) {
669  return !d->secretsCollection->isLocked();
670  }
671  else {
672 #endif
673  return d->handle != -1;
674 #ifdef HAVE_KSECRETSSERVICE
675  }
676 #endif
677 }
678 
679 
680 void Wallet::requestChangePassword(WId w) {
681  if( w == 0 )
682  kDebug(285) << "Pass a valid window to KWallet::Wallet::requestChangePassword().";
683 
684 #ifdef HAVE_KSECRETSSERVICE
685  if (walletLauncher->m_useKSecretsService) {
686  KSecretsService::ChangeCollectionPasswordJob *changePwdJob = d->secretsCollection->changePassword();
687  if (!changePwdJob->exec()) {
688  kDebug(285) << "Cannot execute ChangeCollectionPasswordJob : " << changePwdJob->errorString();
689  }
690  }
691  else {
692 #endif
693  if (d->handle == -1) {
694  return;
695  }
696 
697  // Make sure the password prompt window will be visible and activated
698  KWindowSystem::allowExternalProcessWindowActivation();
699 
700  walletLauncher->getInterface().changePassword(d->name, (qlonglong)w, appid());
701 #ifdef HAVE_KSECRETSSERVICE
702  }
703 #endif
704 }
705 
706 
707 void Wallet::slotWalletClosed(int handle) {
708 #ifdef HAVE_KSECRETSSERVICE
709  if (walletLauncher->m_useKSecretsService) {
710  // TODO: implement this
711  Q_ASSERT(0);
712  }
713  else {
714 #endif
715  if (d->handle == handle) {
716  d->handle = -1;
717  d->folder.clear();
718  d->name.clear();
719  emit walletClosed();
720  }
721 #ifdef HAVE_KSECRETSSERVICE
722  }
723 #endif
724 }
725 
726 
727 QStringList Wallet::folderList() {
728 #ifdef HAVE_KSECRETSSERVICE
729  if (walletLauncher->m_useKSecretsService) {
730  QStringList result;
731 
732  KSecretsService::StringStringMap attrs;
733  attrs[KSS_ATTR_ENTRYFOLDER] = ""; // search for items having this attribute no matter what value it has
734  KSecretsService::SearchCollectionItemsJob *searchJob = d->secretsCollection->searchItems(attrs);
735 
736  if (searchJob->exec()) {
737  KSecretsService::ReadCollectionItemsJob::ItemList itemList = searchJob->items();
738  foreach( const KSecretsService::ReadCollectionItemsJob::Item &item, itemList ) {
739  KSecretsService::ReadItemPropertyJob *readAttrsJob = item->attributes();
740  if (readAttrsJob->exec()) {
741  KSecretsService::StringStringMap attrs = readAttrsJob->propertyValue().value<KSecretsService::StringStringMap>();
742  const QString folder = attrs[KSS_ATTR_ENTRYFOLDER];
743  if (!folder.isEmpty() && !result.contains(folder)) {
744  result.append(folder);
745  }
746  }
747  else {
748  kDebug(285) << "Cannot read item attributes : " << readAttrsJob->errorString();
749  }
750  }
751  }
752  else {
753  kDebug(285) << "Cannot execute ReadCollectionItemsJob : " << searchJob->errorString();
754  }
755  return result;
756  }
757  else {
758 #endif
759  if (d->handle == -1) {
760  return QStringList();
761  }
762 
763  QDBusReply<QStringList> r = walletLauncher->getInterface().folderList(d->handle, appid());
764  if (!r.isValid())
765  {
766  kDebug(285) << "Invalid DBus reply: " << r.error();
767  return QStringList();
768  }
769  else
770  return r;
771 #ifdef HAVE_KSECRETSSERVICE
772  }
773 #endif
774 }
775 
776 
777 QStringList Wallet::entryList() {
778 #ifdef HAVE_KSECRETSSERVICE
779  if (walletLauncher->m_useKSecretsService) {
780  QStringList result;
781  KSecretsService::StringStringMap attrs;
782  attrs[KSS_ATTR_ENTRYFOLDER] = d->folder;
783  KSecretsService::SearchCollectionItemsJob *readItemsJob = d->secretsCollection->searchItems( attrs );
784  if ( readItemsJob->exec() ) {
785  foreach( KSecretsService::SearchCollectionItemsJob::Item item, readItemsJob->items() ) {
786  KSecretsService::ReadItemPropertyJob *readLabelJob = item->label();
787  if ( readLabelJob->exec() ) {
788  result.append( readLabelJob->propertyValue().toString() );
789  }
790  else {
791  kDebug(285) << "Cannot execute readLabelJob" << readItemsJob->errorString();
792  }
793  }
794  }
795  else {
796  kDebug(285) << "Cannot execute readItemsJob" << readItemsJob->errorString();
797  }
798  return result;
799  }
800  else {
801 #endif
802  if (d->handle == -1) {
803  return QStringList();
804  }
805 
806  QDBusReply<QStringList> r = walletLauncher->getInterface().entryList(d->handle, d->folder, appid());
807  if (!r.isValid())
808  {
809  kDebug(285) << "Invalid DBus reply: " << r.error();
810  return QStringList();
811  }
812  else
813  return r;
814 #ifdef HAVE_KSECRETSSERVICE
815  }
816 #endif
817 }
818 
819 
820 bool Wallet::hasFolder(const QString& f) {
821 #ifdef HAVE_KSECRETSSERVICE
822  if (walletLauncher->m_useKSecretsService) {
823  // FIXME: well, this is not the best implementation, but it's done quickly :)
824  // the best way would be to searchItems with the attribute label having the value f
825  // doing that would reduce DBus traffic. But KWallet API wille not last.
826  QStringList folders = folderList();
827  return folders.contains(f);
828  }
829  else {
830 #endif
831  if (d->handle == -1) {
832  return false;
833  }
834 
835  QDBusReply<bool> r = walletLauncher->getInterface().hasFolder(d->handle, f, appid());
836  if (!r.isValid())
837  {
838  kDebug(285) << "Invalid DBus reply: " << r.error();
839  return false;
840  }
841  else
842  return r;
843 #ifdef HAVE_KSECRETSSERVICE
844  }
845 #endif
846 }
847 
848 
849 bool Wallet::createFolder(const QString& f) {
850 #ifdef HAVE_KSECRETSSERVICE
851  if (walletLauncher->m_useKSecretsService) {
852  QString strDummy("");
853  d->folder = f;
854  d->writeEntry( f, strDummy, KWallet::Wallet::Unknown );
855  return true;
856  }
857  else {
858 #endif
859  if (d->handle == -1) {
860  return false;
861  }
862 
863  if (!hasFolder(f)) {
864  QDBusReply<bool> r = walletLauncher->getInterface().createFolder(d->handle, f, appid());
865 
866  if (!r.isValid())
867  {
868  kDebug(285) << "Invalid DBus reply: " << r.error();
869  return false;
870  }
871  else
872  return r;
873  }
874 
875  return true; // folder already exists
876 #ifdef HAVE_KSECRETSSERVICE
877  }
878 #endif
879 }
880 
881 
882 bool Wallet::setFolder(const QString& f) {
883  bool rc = false;
884 
885 #ifdef HAVE_KSECRETSSERVICE
886  if (walletLauncher->m_useKSecretsService) {
887  if (hasFolder(f)) {
888  d->folder = f;
889  rc = true;
890  }
891  }
892  else {
893 #endif
894  if (d->handle == -1) {
895  return rc;
896  }
897 
898  // Don't do this - the folder could have disappeared?
899  #if 0
900  if (f == d->folder) {
901  return true;
902  }
903  #endif
904 
905  if (hasFolder(f)) {
906  d->folder = f;
907  rc = true;
908  }
909 #ifdef HAVE_KSECRETSSERVICE
910  }
911 #endif
912 
913  return rc;
914 }
915 
916 
917 bool Wallet::removeFolder(const QString& f) {
918 #ifdef HAVE_KSECRETSSERVICE
919  if (walletLauncher->m_useKSecretsService) {
920  bool result = false;
921  // search for all items having the folder f then delete them
922  KSecretsService::StringStringMap attrs;
923  attrs[KSS_ATTR_ENTRYFOLDER] = f;
924  KSecretsService::SearchCollectionItemsJob *searchJob = d->secretsCollection->searchItems(attrs);
925  if (searchJob->exec()) {
926  KSecretsService::SearchCollectionItemsJob::ItemList itemList = searchJob->items();
927  if ( !itemList.isEmpty() ) {
928  result = true;
929  foreach( const KSecretsService::SearchCollectionItemsJob::Item &item, itemList ) {
930  KSecretsService::SecretItemDeleteJob *deleteJob = item->deleteItem();
931  if (!deleteJob->exec()) {
932  kDebug(285) << "Cannot delete item : " << deleteJob->errorString();
933  result = false;
934  }
935  result &= true;
936  }
937  }
938  }
939  else {
940  kDebug(285) << "Cannot execute KSecretsService::SearchCollectionItemsJob : " << searchJob->errorString();
941  }
942  return result;
943  }
944  else {
945 #endif
946  if (d->handle == -1) {
947  return false;
948  }
949 
950  QDBusReply<bool> r = walletLauncher->getInterface().removeFolder(d->handle, f, appid());
951  if (d->folder == f) {
952  setFolder(QString());
953  }
954 
955  if (!r.isValid())
956  {
957  kDebug(285) << "Invalid DBus reply: " << r.error();
958  return false;
959  }
960  else
961  return r;
962 #ifdef HAVE_KSECRETSSERVICE
963  }
964 #endif
965 }
966 
967 
968 const QString& Wallet::currentFolder() const {
969  return d->folder;
970 }
971 
972 #ifdef HAVE_KSECRETSSERVICE
973 QExplicitlySharedDataPointer<KSecretsService::SecretItem> Wallet::WalletPrivate::findItem( const QString& key ) const
974 {
975  QExplicitlySharedDataPointer<KSecretsService::SecretItem> result;
976  KSecretsService::StringStringMap attrs;
977  attrs[KSS_ATTR_ENTRYFOLDER] = folder;
978  attrs["Label"] = key;
979  KSecretsService::SearchCollectionItemsJob *searchJob = secretsCollection->searchItems(attrs);
980  if (searchJob->exec()) {
981  KSecretsService::SearchCollectionItemsJob::ItemList itemList = searchJob->items();
982  if ( !itemList.isEmpty() ) {
983  result = itemList.first();
984  }
985  else {
986  kDebug(285) << "entry named " << key << " not found in folder " << folder;
987  }
988  }
989  else {
990  kDebug(285) << "Cannot exec KSecretsService::SearchCollectionItemsJob : " << searchJob->errorString();
991  }
992 
993  return result;
994 }
995 
996 template <typename T>
997 int Wallet::WalletPrivate::readEntry(const QString& key, T& value) const
998 {
999  int rc = -1;
1000  QExplicitlySharedDataPointer<KSecretsService::SecretItem> item = findItem(key);
1001  if ( item ) {
1002  KSecretsService::GetSecretItemSecretJob *readJob = item->getSecret();
1003  if ( readJob->exec() ) {
1004  KSecretsService::Secret theSecret = readJob->secret();
1005  kDebug(285) << "Secret contentType is " << theSecret.contentType();
1006  value = theSecret.value().value<T>();
1007  rc = 0;
1008  }
1009  else {
1010  kDebug(285) << "Cannot exec GetSecretItemSecretJob : " << readJob->errorString();
1011  }
1012  }
1013  return rc;
1014 }
1015 
1016 bool Wallet::WalletPrivate::readSecret(const QString& key, KSecretsService::Secret& value) const
1017 {
1018  bool result = false;
1019  QExplicitlySharedDataPointer<KSecretsService::SecretItem> item = findItem(key);
1020  if ( item ) {
1021  KSecretsService::GetSecretItemSecretJob *readJob = item->getSecret();
1022  if ( readJob->exec() ) {
1023  value = readJob->secret();
1024  result = true;
1025  }
1026  else {
1027  kDebug(285) << "Cannot exec GetSecretItemSecretJob : " << readJob->errorString();
1028  }
1029  }
1030  return result;
1031 }
1032 #endif
1033 
1034 int Wallet::readEntry(const QString& key, QByteArray& value) {
1035  int rc = -1;
1036 
1037 #ifdef HAVE_KSECRETSSERVICE
1038  if (walletLauncher->m_useKSecretsService) {
1039  return d->readEntry<QByteArray>(key, value);
1040  }
1041  else {
1042 #endif
1043  if (d->handle == -1) {
1044  return rc;
1045  }
1046 
1047  QDBusReply<QByteArray> r = walletLauncher->getInterface().readEntry(d->handle, d->folder, key, appid());
1048  if (r.isValid()) {
1049  value = r;
1050  rc = 0;
1051  }
1052 #ifdef HAVE_KSECRETSSERVICE
1053  }
1054 #endif
1055 
1056  return rc;
1057 }
1058 
1059 #ifdef HAVE_KSECRETSSERVICE
1060 struct Wallet::WalletPrivate::InsertIntoEntryList {
1061  InsertIntoEntryList( QMap< QString, QByteArray> &value ) : _value( value ) {}
1062  bool operator() ( Wallet::WalletPrivate*, const QString& label, KSecretsService::SecretItem* item ) {
1063  bool result = false;
1064  KSecretsService::GetSecretItemSecretJob *readSecretJob = item->getSecret();
1065  if ( readSecretJob->exec() ) {
1066  _value.insert( label, readSecretJob->secret().value().toByteArray() );
1067  result = true;
1068  }
1069  else {
1070  kDebug(285) << "Cannot execute GetSecretItemSecretJob " << readSecretJob->errorString();
1071  }
1072  return result;
1073  }
1074  QMap< QString, QByteArray > _value;
1075 };
1076 #endif
1077 
1078 int Wallet::readEntryList(const QString& key, QMap<QString, QByteArray>& value) {
1079 
1080  int rc = -1;
1081 
1082 #ifdef HAVE_KSECRETSSERVICE
1083  if (walletLauncher->m_useKSecretsService) {
1084  rc = d->forEachItemThatMatches( key, WalletPrivate::InsertIntoEntryList( value ) );
1085  }
1086  else {
1087 #endif
1088  registerTypes();
1089 
1090  if (d->handle == -1) {
1091  return rc;
1092  }
1093 
1094  QDBusReply<QVariantMap> r = walletLauncher->getInterface().readEntryList(d->handle, d->folder, key, appid());
1095  if (r.isValid()) {
1096  rc = 0;
1097  // convert <QString, QVariant> to <QString, QByteArray>
1098  const QVariantMap val = r.value();
1099  for( QVariantMap::const_iterator it = val.begin(); it != val.end(); ++it ) {
1100  value.insert(it.key(), it.value().toByteArray());
1101  }
1102  }
1103 #ifdef HAVE_KSECRETSSERVICE
1104  }
1105 #endif
1106 
1107  return rc;
1108 }
1109 
1110 
1111 int Wallet::renameEntry(const QString& oldName, const QString& newName) {
1112  int rc = -1;
1113 
1114 #ifdef HAVE_KSECRETSSERVICE
1115  if (walletLauncher->m_useKSecretsService) {
1116  QExplicitlySharedDataPointer<KSecretsService::SecretItem> item = d->findItem(oldName);
1117  if (item) {
1118  KSecretsService::WriteItemPropertyJob *writeJob = item->setLabel(newName);
1119  if (!writeJob->exec()) {
1120  kDebug(285) << "Cannot exec WriteItemPropertyJob : " << writeJob->errorString();
1121  }
1122  rc = writeJob->error();
1123  }
1124  else {
1125  kDebug(285) << "Cannot locate item " << oldName << " in folder " << d->folder;
1126  }
1127  }
1128  else {
1129 #endif
1130  if (d->handle == -1) {
1131  return rc;
1132  }
1133 
1134  QDBusReply<int> r = walletLauncher->getInterface().renameEntry(d->handle, d->folder, oldName, newName, appid());
1135  if (r.isValid()) {
1136  rc = r;
1137  }
1138 #ifdef HAVE_KSECRETSSERVICE
1139  }
1140 #endif
1141 
1142  return rc;
1143 }
1144 
1145 
1146 int Wallet::readMap(const QString& key, QMap<QString,QString>& value) {
1147  int rc = -1;
1148 
1149 #ifdef HAVE_KSECRETSSERVICE
1150  if (walletLauncher->m_useKSecretsService) {
1151  QByteArray ba;
1152  rc = d->readEntry< QByteArray >(key, ba);
1153  if ( rc == 0 && !ba.isEmpty()){
1154  QDataStream ds( &ba, QIODevice::ReadOnly );
1155  ds >> value;
1156  }
1157  }
1158  else {
1159 #endif
1160  registerTypes();
1161 
1162  if (d->handle == -1) {
1163  return rc;
1164  }
1165 
1166  QDBusReply<QByteArray> r = walletLauncher->getInterface().readMap(d->handle, d->folder, key, appid());
1167  if (r.isValid()) {
1168  rc = 0;
1169  QByteArray v = r;
1170  if (!v.isEmpty()) {
1171  QDataStream ds(&v, QIODevice::ReadOnly);
1172  ds >> value;
1173  }
1174  }
1175 #ifdef HAVE_KSECRETSSERVICE
1176  }
1177 #endif
1178 
1179  return rc;
1180 }
1181 
1182 #ifdef HAVE_KSECRETSSERVICE
1183 struct Wallet::WalletPrivate::InsertIntoMapList {
1184  InsertIntoMapList( QMap< QString, QMap< QString, QString > > &value ) : _value( value ) {}
1185  bool operator() ( Wallet::WalletPrivate* d, const QString& label, KSecretsService::SecretItem* ) {
1186  bool result = false;
1187  QMap<QString, QString> map;
1188  if ( d->readEntry< QMap< QString, QString> >(label, map) ) {
1189  _value.insert( label, map );
1190  result = true;
1191  }
1192  return result;
1193  }
1194  QMap< QString, QMap< QString, QString> > &_value;
1195 };
1196 #endif
1197 
1198 int Wallet::readMapList(const QString& key, QMap<QString, QMap<QString, QString> >& value) {
1199  int rc = -1;
1200 
1201 #ifdef HAVE_KSECRETSSERVICE
1202  if (walletLauncher->m_useKSecretsService) {
1203  rc = d->forEachItemThatMatches( key, WalletPrivate::InsertIntoMapList( value ) );
1204  }
1205  else {
1206 #endif
1207  registerTypes();
1208 
1209  if (d->handle == -1) {
1210  return rc;
1211  }
1212 
1213  QDBusReply<QVariantMap> r =
1214  walletLauncher->getInterface().readMapList(d->handle, d->folder, key, appid());
1215  if (r.isValid()) {
1216  rc = 0;
1217  const QVariantMap val = r.value();
1218  for( QVariantMap::const_iterator it = val.begin(); it != val.end(); ++it ) {
1219  QByteArray mapData = it.value().toByteArray();
1220  if (!mapData.isEmpty()) {
1221  QDataStream ds(&mapData, QIODevice::ReadOnly);
1222  QMap<QString,QString> v;
1223  ds >> v;
1224  value.insert(it.key(), v);
1225  }
1226  }
1227  }
1228 #ifdef HAVE_KSECRETSSERVICE
1229  }
1230 #endif
1231 
1232  return rc;
1233 }
1234 
1235 
1236 int Wallet::readPassword(const QString& key, QString& value) {
1237  int rc = -1;
1238 
1239 #ifdef HAVE_KSECRETSSERVICE
1240  if (walletLauncher->m_useKSecretsService) {
1241  rc = d->readEntry<QString>(key, value);
1242  }
1243  else {
1244 #endif
1245  if (d->handle == -1) {
1246  return rc;
1247  }
1248 
1249  QDBusReply<QString> r = walletLauncher->getInterface().readPassword(d->handle, d->folder, key, appid());
1250  if (r.isValid()) {
1251  value = r;
1252  rc = 0;
1253  }
1254 #ifdef HAVE_KSECRETSSERVICE
1255  }
1256 #endif
1257 
1258  return rc;
1259 }
1260 
1261 #ifdef HAVE_KSECRETSSERVICE
1262 struct Wallet::WalletPrivate::InsertIntoPasswordList {
1263  InsertIntoPasswordList( QMap< QString, QString> &value ) : _value( value ) {}
1264  bool operator() ( Wallet::WalletPrivate* d, const QString& label, KSecretsService::SecretItem* ) {
1265  bool result = false;
1266  QString pwd;
1267  if ( d->readEntry<QString>( label, pwd ) == 0 ) {
1268  _value.insert( label, pwd );
1269  result = true;
1270  }
1271  return result;
1272  }
1273  QMap< QString, QString > &_value;
1274 };
1275 #endif
1276 
1277 int Wallet::readPasswordList(const QString& key, QMap<QString, QString>& value) {
1278  int rc = -1;
1279 
1280 #ifdef HAVE_KSECRETSSERVICE
1281  if (walletLauncher->m_useKSecretsService) {
1282  rc = d->forEachItemThatMatches( key, WalletPrivate::InsertIntoPasswordList( value ) );
1283  }
1284  else {
1285 #endif
1286  registerTypes();
1287 
1288  if (d->handle == -1) {
1289  return rc;
1290  }
1291 
1292  QDBusReply<QVariantMap> r = walletLauncher->getInterface().readPasswordList(d->handle, d->folder, key, appid());
1293  if (r.isValid()) {
1294  rc = 0;
1295  const QVariantMap val = r.value();
1296  for( QVariantMap::const_iterator it = val.begin(); it != val.end(); ++it ) {
1297  value.insert(it.key(), it.value().toString());
1298  }
1299  }
1300 #ifdef HAVE_KSECRETSSERVICE
1301  }
1302 #endif
1303 
1304  return rc;
1305 }
1306 
1307 
1308 int Wallet::writeEntry(const QString& key, const QByteArray& value, EntryType entryType) {
1309  int rc = -1;
1310 
1311 #ifdef HAVE_KSECRETSSERVICE
1312  if (walletLauncher->m_useKSecretsService) {
1313  rc = d->writeEntry( key, value, entryType );
1314  }
1315  else {
1316 #endif
1317  if (d->handle == -1) {
1318  return rc;
1319  }
1320 
1321  QDBusReply<int> r = walletLauncher->getInterface().writeEntry(d->handle, d->folder, key, value, int(entryType), appid());
1322  if (r.isValid()) {
1323  rc = r;
1324  }
1325 #ifdef HAVE_KSECRETSSERVICE
1326  }
1327 #endif
1328 
1329  return rc;
1330 }
1331 
1332 
1333 int Wallet::writeEntry(const QString& key, const QByteArray& value) {
1334  int rc = -1;
1335 
1336 #ifdef HAVE_KSECRETSSERVICE
1337  if (walletLauncher->m_useKSecretsService) {
1338  rc = writeEntry( key, value, Stream );
1339  }
1340  else {
1341 #endif
1342  if (d->handle == -1) {
1343  return rc;
1344  }
1345 
1346  QDBusReply<int> r = walletLauncher->getInterface().writeEntry(d->handle, d->folder, key, value, appid());
1347  if (r.isValid()) {
1348  rc = r;
1349  }
1350 #ifdef HAVE_KSECRETSSERVICE
1351  }
1352 #endif
1353 
1354  return rc;
1355 }
1356 
1357 
1358 int Wallet::writeMap(const QString& key, const QMap<QString,QString>& value) {
1359  int rc = -1;
1360 
1361 #ifdef HAVE_KSECRETSSERVICE
1362  if (walletLauncher->m_useKSecretsService) {
1363  d->writeEntry( key, value, Map );
1364  }
1365  else {
1366 #endif
1367  registerTypes();
1368 
1369  if (d->handle == -1) {
1370  return rc;
1371  }
1372 
1373  QByteArray mapData;
1374  QDataStream ds(&mapData, QIODevice::WriteOnly);
1375  ds << value;
1376  QDBusReply<int> r = walletLauncher->getInterface().writeMap(d->handle, d->folder, key, mapData, appid());
1377  if (r.isValid()) {
1378  rc = r;
1379  }
1380 #ifdef HAVE_KSECRETSSERVICE
1381  }
1382 #endif
1383 
1384  return rc;
1385 }
1386 
1387 
1388 int Wallet::writePassword(const QString& key, const QString& value) {
1389  int rc = -1;
1390 
1391 #ifdef HAVE_KSECRETSSERVICE
1392  if (walletLauncher->m_useKSecretsService) {
1393  rc = d->writeEntry( key, value, Password );
1394  }
1395  else {
1396 #endif
1397  if (d->handle == -1) {
1398  return rc;
1399  }
1400 
1401  QDBusReply<int> r = walletLauncher->getInterface().writePassword(d->handle, d->folder, key, value, appid());
1402  if (r.isValid()) {
1403  rc = r;
1404  }
1405 #ifdef HAVE_KSECRETSSERVICE
1406  }
1407 #endif
1408 
1409  return rc;
1410 }
1411 
1412 
1413 bool Wallet::hasEntry(const QString& key) {
1414 #ifdef HAVE_KSECRETSSERVICE
1415  if (walletLauncher->m_useKSecretsService) {
1416  QExplicitlySharedDataPointer<KSecretsService::SecretItem> item = d->findItem( key );
1417  return item;
1418  }
1419  else {
1420 #endif
1421  if (d->handle == -1) {
1422  return false;
1423  }
1424 
1425  QDBusReply<bool> r = walletLauncher->getInterface().hasEntry(d->handle, d->folder, key, appid());
1426  if (!r.isValid())
1427  {
1428  kDebug(285) << "Invalid DBus reply: " << r.error();
1429  return false;
1430  }
1431  else
1432  return r;
1433 #ifdef HAVE_KSECRETSSERVICE
1434  }
1435 #endif
1436 }
1437 
1438 
1439 int Wallet::removeEntry(const QString& key) {
1440  int rc = -1;
1441 
1442 #ifdef HAVE_KSECRETSSERVICE
1443  if (walletLauncher->m_useKSecretsService) {
1444  QExplicitlySharedDataPointer<KSecretsService::SecretItem> item = d->findItem( key );
1445  if ( item ) {
1446  KSecretsService::SecretItemDeleteJob *deleteJob = item->deleteItem();
1447  if ( !deleteJob->exec() ) {
1448  kDebug(285) << "Cannot execute SecretItemDeleteJob " << deleteJob->errorString();
1449  }
1450  rc = deleteJob->error();
1451  }
1452  }
1453  else {
1454 #endif
1455  if (d->handle == -1) {
1456  return rc;
1457  }
1458 
1459  QDBusReply<int> r = walletLauncher->getInterface().removeEntry(d->handle, d->folder, key, appid());
1460  if (r.isValid()) {
1461  rc = r;
1462  }
1463 #ifdef HAVE_KSECRETSSERVICE
1464  }
1465 #endif
1466 
1467  return rc;
1468 }
1469 
1470 
1471 Wallet::EntryType Wallet::entryType(const QString& key) {
1472  int rc = 0;
1473 
1474 #ifdef HAVE_KSECRETSSERVICE
1475  if (walletLauncher->m_useKSecretsService) {
1476  QExplicitlySharedDataPointer<KSecretsService::SecretItem> item = d->findItem( key );
1477  if ( item ) {
1478  KSecretsService::ReadItemPropertyJob *readAttrsJob = item->attributes();
1479  if ( readAttrsJob->exec() ) {
1480  KSecretsService::StringStringMap attrs = readAttrsJob->propertyValue().value<KSecretsService::StringStringMap>();
1481  if ( attrs.contains( KSS_ATTR_WALLETTYPE ) ) {
1482  QString entryType = attrs[KSS_ATTR_WALLETTYPE];
1483  bool ok = false;
1484  rc = entryType.toInt( &ok );
1485  if ( !ok ) {
1486  rc = 0;
1487  kDebug(285) << KSS_ATTR_WALLETTYPE << " attribute holds non int value " << attrs[KSS_ATTR_WALLETTYPE];
1488  }
1489  }
1490  }
1491  else {
1492  kDebug(285) << "Cannot execute GetSecretItemSecretJob " << readAttrsJob->errorString();
1493  }
1494  }
1495  }
1496  else {
1497 #endif
1498  if (d->handle == -1) {
1499  return Wallet::Unknown;
1500  }
1501 
1502  QDBusReply<int> r = walletLauncher->getInterface().entryType(d->handle, d->folder, key, appid());
1503  if (r.isValid()) {
1504  rc = r;
1505  }
1506 #ifdef HAVE_KSECRETSSERVICE
1507  }
1508 #endif
1509  return static_cast<EntryType>(rc);
1510 }
1511 
1512 
1513 void Wallet::WalletPrivate::walletServiceUnregistered()
1514 {
1515  if (handle >= 0) {
1516  q->slotWalletClosed(handle);
1517  }
1518 }
1519 
1520 void Wallet::slotFolderUpdated(const QString& wallet, const QString& folder) {
1521 #ifdef HAVE_KSECRETSSERVICE
1522  if (walletLauncher->m_useKSecretsService) {
1523  // TODO: implement this
1524  Q_ASSERT(0);
1525  }
1526  else {
1527 #endif
1528  if (d->name == wallet) {
1529  emit folderUpdated(folder);
1530  }
1531 #ifdef HAVE_KSECRETSSERVICE
1532  }
1533 #endif
1534 }
1535 
1536 
1537 void Wallet::slotFolderListUpdated(const QString& wallet) {
1538 #ifdef HAVE_KSECRETSSERVICE
1539  if (walletLauncher->m_useKSecretsService) {
1540  // TODO: implement this
1541  Q_ASSERT(0);
1542  }
1543  else {
1544 #endif
1545  if (d->name == wallet) {
1546  emit folderListUpdated();
1547  }
1548 #ifdef HAVE_KSECRETSSERVICE
1549  }
1550 #endif
1551 }
1552 
1553 
1554 void Wallet::slotApplicationDisconnected(const QString& wallet, const QString& application) {
1555 #ifdef HAVE_KSECRETSSERVICE
1556  if (walletLauncher->m_useKSecretsService) {
1557  // TODO: implement this
1558  Q_ASSERT(0);
1559  }
1560  else {
1561 #endif
1562  if (d->handle >= 0
1563  && d->name == wallet
1564  && application == appid()) {
1565  slotWalletClosed(d->handle);
1566  }
1567 #ifdef HAVE_KSECRETSSERVICE
1568  }
1569 #endif
1570 }
1571 
1572 void Wallet::walletAsyncOpened(int tId, int handle) {
1573 #ifdef HAVE_KSECRETSSERVICE
1574  if (walletLauncher->m_useKSecretsService) {
1575  // TODO: implement this
1576  Q_ASSERT(0);
1577  }
1578  else {
1579 #endif
1580  // ignore responses to calls other than ours
1581  if (d->transactionId != tId || d->handle != -1) {
1582  return;
1583  }
1584 
1585  // disconnect the async signal
1586  disconnect(this, SLOT(walletAsyncOpened(int,int)));
1587 
1588  d->handle = handle;
1589  emit walletOpened(handle > 0);
1590 #ifdef HAVE_KSECRETSSERVICE
1591  }
1592 #endif
1593 }
1594 
1595 void Wallet::emitWalletAsyncOpenError() {
1596  emit walletOpened(false);
1597 }
1598 
1599 void Wallet::emitWalletOpened() {
1600  emit walletOpened(true);
1601 }
1602 
1603 bool Wallet::folderDoesNotExist(const QString& wallet, const QString& folder)
1604 {
1605 #ifdef HAVE_KSECRETSSERVICE
1606  if (walletLauncher->m_useKSecretsService) {
1607  kDebug(285) << "WARNING: changing semantics of folderDoesNotExist with KSS: will prompt for the password";
1608  Wallet *w = openWallet( wallet, 0, Synchronous );
1609  if ( w ) {
1610  return !w->hasFolder( folder );
1611  }
1612  else {
1613  return true;
1614  }
1615  }
1616  else {
1617 #endif
1618  QDBusReply<bool> r = walletLauncher->getInterface().folderDoesNotExist(wallet, folder);
1619  if (!r.isValid())
1620  {
1621  kDebug(285) << "Invalid DBus reply: " << r.error();
1622  return false;
1623  }
1624  else
1625  return r;
1626 #ifdef HAVE_KSECRETSSERVICE
1627  }
1628 #endif
1629 }
1630 
1631 
1632 bool Wallet::keyDoesNotExist(const QString& wallet, const QString& folder, const QString& key)
1633 {
1634 #ifdef HAVE_KSECRETSSERVICE
1635  if (walletLauncher->m_useKSecretsService) {
1636  kDebug(285) << "WARNING: changing semantics of keyDoesNotExist with KSS: will prompt for the password";
1637  Wallet *w = openWallet( wallet, 0, Synchronous );
1638  if ( w ) {
1639  return !w->hasEntry(key);
1640  }
1641  return false;
1642  }
1643  else {
1644 #endif
1645  QDBusReply<bool> r = walletLauncher->getInterface().keyDoesNotExist(wallet, folder, key);
1646  if (!r.isValid())
1647  {
1648  kDebug(285) << "Invalid DBus reply: " << r.error();
1649  return false;
1650  }
1651  else
1652  return r;
1653 #ifdef HAVE_KSECRETSSERVICE
1654  }
1655 #endif
1656 }
1657 
1658 void Wallet::virtual_hook(int, void*) {
1659  //BASE::virtual_hook( id, data );
1660 }
1661 
1662 
1663 KWalletDLauncher::KWalletDLauncher()
1664  : m_wallet(0),
1665  m_cgroup(KSharedConfig::openConfig("kwalletrc", KConfig::NoGlobals)->group("Wallet"))
1666 {
1667  m_useKSecretsService = m_cgroup.readEntry("UseKSecretsService", false);
1668 #ifdef HAVE_KSECRETSSERVICE
1669  if (m_useKSecretsService) {
1670  // NOOP
1671  }
1672  else {
1673 #endif
1674  m_wallet = new org::kde::KWallet(QString::fromLatin1(s_kwalletdServiceName), "/modules/kwalletd", QDBusConnection::sessionBus());
1675 #ifdef HAVE_KSECRETSSERVICE
1676  }
1677 #endif
1678 }
1679 
1680 KWalletDLauncher::~KWalletDLauncher()
1681 {
1682  delete m_wallet;
1683 }
1684 
1685 org::kde::KWallet &KWalletDLauncher::getInterface()
1686 {
1687 // Q_ASSERT(!m_useKSecretsService);
1688  Q_ASSERT(m_wallet != 0);
1689 
1690  // check if kwalletd is already running
1691  if (!QDBusConnection::sessionBus().interface()->isServiceRegistered(QString::fromLatin1(s_kwalletdServiceName)))
1692  {
1693  // not running! check if it is enabled.
1694  bool walletEnabled = m_cgroup.readEntry("Enabled", true);
1695  if (walletEnabled) {
1696  // wallet is enabled! try launching it
1697  QString error;
1698  int ret = KToolInvocation::startServiceByDesktopPath("kwalletd.desktop", QStringList(), &error);
1699  if (ret > 0)
1700  {
1701  kError(285) << "Couldn't start kwalletd: " << error << endl;
1702  }
1703 
1704  if
1705  (!QDBusConnection::sessionBus().interface()->isServiceRegistered(QString::fromLatin1(s_kwalletdServiceName))) {
1706  kDebug(285) << "The kwalletd service is still not registered";
1707  } else {
1708  kDebug(285) << "The kwalletd service has been registered";
1709  }
1710  } else {
1711  kError(285) << "The kwalletd service has been disabled";
1712  }
1713  }
1714 
1715  return *m_wallet;
1716 }
1717 
1718 } // namespace KWallet
1719 
1720 #include "kwallet.moc"
KWallet::Wallet::Synchronous
Definition: kwallet.h:135
KWallet::Wallet::hasEntry
virtual bool hasEntry(const QString &key)
Determine if the current folder has they entry key.
Definition: kwallet.cpp:1413
KWallet::Wallet::requestChangePassword
virtual void requestChangePassword(WId w)
Request to the wallet service to change the password of the current wallet.
Definition: kwallet.cpp:680
KWallet::Wallet::Wallet
Wallet(int handle, const QString &name)
Construct a KWallet object.
Definition: kwallet.cpp:243
KWallet::Wallet::walletName
virtual const QString & walletName() const
The name of the current wallet.
Definition: kwallet.cpp:661
readEntry
KAutostart::StartPhase readEntry(const KConfigGroup &group, const char *key, const KAutostart::StartPhase &aDefault)
KWallet::Wallet::setFolder
virtual bool setFolder(const QString &f)
Set the current working folder to f.
Definition: kwallet.cpp:882
KSharedConfig
KWallet::Wallet::Unknown
Definition: kwallet.h:80
KWallet::Wallet::renameEntry
virtual int renameEntry(const QString &oldName, const QString &newName)
Rename the entry oldName to newName.
Definition: kwallet.cpp:1111
kdebug.h
KWallet::appid
static QString appid()
Definition: kwallet.cpp:76
KWallet::Wallet
KDE Wallet.
Definition: kwallet.h:62
KWallet::Wallet::entryType
virtual EntryType entryType(const QString &key)
Determine the type of the entry key in this folder.
Definition: kwallet.cpp:1471
KWallet::Wallet::folderListUpdated
void folderListUpdated()
Emitted when the folder list is changed in this wallet.
T
#define T
KWallet::Wallet::virtual_hook
virtual void virtual_hook(int id, void *data)
Definition: kwallet.cpp:1658
StringToStringStringMapMap
QMap< QString, StringStringMap > StringToStringStringMapMap
Definition: kwallet_mac.cpp:48
QByteArray
group
KWallet::Wallet::Map
Definition: kwallet.h:80
QDBusReply
QDataStream
KStandardShortcut::label
QString label(StandardShortcut id)
Returns a localized label for user-visible display.
Definition: kstandardshortcut.cpp:267
K_GLOBAL_STATIC
#define K_GLOBAL_STATIC(TYPE, NAME)
QMap
QStringList::contains
bool contains(const QString &str, Qt::CaseSensitivity cs) const
QByteArray::isEmpty
bool isEmpty() const
KStandardAction::name
const char * name(StandardAction id)
This will return the internal name of a given standard action.
Definition: kstandardaction.cpp:223
KWallet::Wallet::~Wallet
virtual ~Wallet()
Destroy a KWallet object.
Definition: kwallet.cpp:272
kError
static QDebug kError(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
KWallet::Wallet::isEnabled
static bool isEnabled()
Determine if the KDE wallet is enabled.
Definition: kwallet.cpp:352
KWallet::Wallet::readMap
virtual int readMap(const QString &key, QMap< QString, QString > &value)
Read the map entry key from the current folder.
Definition: kwallet.cpp:1146
QDBusReply::isValid
bool isValid() const
QDBusConnection::sessionBus
QDBusConnection sessionBus()
KWallet::Wallet::removeEntry
virtual int removeEntry(const QString &key)
Remove the entry key from the current folder.
Definition: kwallet.cpp:1439
KComponentData::aboutData
const KAboutData * aboutData() const
StringByteArrayMap
QMap< QString, QByteArray > StringByteArrayMap
Definition: kwallet.cpp:52
KWallet::Wallet::readPasswordList
int readPasswordList(const QString &key, QMap< QString, QString > &value)
Read the password entry key from the current folder.
Definition: kwallet.cpp:1277
ktoolinvocation.h
kDebug
static QDebug kDebug(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
QObject::disconnect
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
KWallet::Wallet::openWallet
static Wallet * openWallet(const QString &name, WId w, OpenType ot=Synchronous)
Open the wallet name.
Definition: kwallet.cpp:452
KWallet::Wallet::OpenType
OpenType
Definition: kwallet.h:135
KWallet::Wallet::writePassword
virtual int writePassword(const QString &key, const QString &value)
Write key = value as a password to the current folder.
Definition: kwallet.cpp:1388
KWallet::Wallet::walletOpened
void walletOpened(bool success)
Emitted when a wallet is opened in asynchronous mode.
KWallet::Wallet::Stream
Definition: kwallet.h:80
QRegExp
KWallet::Wallet::lockWallet
virtual int lockWallet()
This closes and locks the current wallet.
Definition: kwallet.cpp:624
KWallet::Wallet::hasFolder
virtual bool hasFolder(const QString &f)
Determine if the folder f exists in the wallet.
Definition: kwallet.cpp:820
kglobal.h
KToolInvocation::startServiceByDesktopPath
static int startServiceByDesktopPath(const QString &_name, const QString &URL, QString *error=0, QString *serviceName=0, int *pid=0, const QByteArray &startup_id=QByteArray(), bool noWait=false)
KWallet::Wallet::folderUpdated
void folderUpdated(const QString &folder)
Emitted when a folder in this wallet is updated.
KWallet::Wallet::removeFolder
virtual bool removeFolder(const QString &f)
Remove the folder f and all its entries from the wallet.
Definition: kwallet.cpp:917
QList::append
void append(const T &value)
QString::insert
QString & insert(int position, QChar ch)
QObject
QDBusReply::value
Type value() const
KWallet::Wallet::readPassword
virtual int readPassword(const QString &key, QString &value)
Read the password entry key from the current folder.
Definition: kwallet.cpp:1236
QString::toInt
int toInt(bool *ok, int base) const
KWallet::Wallet::entryList
virtual QStringList entryList()
Return the list of keys of all entries in this folder.
Definition: kwallet.cpp:777
KWallet::Wallet::readEntryList
int readEntryList(const QString &key, QMap< QString, QByteArray > &value)
Read the entries matching key from the current folder.
Definition: kwallet.cpp:1078
QString::isEmpty
bool isEmpty() const
KWallet::Wallet::Asynchronous
Definition: kwallet.h:135
KAboutData
ksharedconfig.h
KComponentData::componentName
QString componentName() const
QString
KWallet::Wallet::walletList
static QStringList walletList()
List all the wallets available.
Definition: kwallet.cpp:299
QStringList
KWallet::Wallet::disconnectApplication
static bool disconnectApplication(const QString &wallet, const QString &app)
Disconnect the application app from wallet.
Definition: kwallet.cpp:560
KWallet::Wallet::walletClosed
void walletClosed()
Emitted when this wallet is closed.
KWallet::Wallet::readEntry
virtual int readEntry(const QString &key, QByteArray &value)
Read the entry key from the current folder.
Definition: kwallet.cpp:1034
KWallet::Wallet::changePassword
static void changePassword(const QString &name, WId w)
Request to the wallet service to change the password of the wallet name.
Definition: kwallet.cpp:328
KStandardGuiItem::ok
KGuiItem ok()
Returns the 'Ok' gui item.
Definition: kstandardguiitem.cpp:107
KSS_ATTR_ENTRYFOLDER
#define KSS_ATTR_ENTRYFOLDER
NOTE: KSecretsService folder semantics The KWallet API uses folders for organising items...
Definition: kwallet.h:46
KWindowSystem::allowExternalProcessWindowActivation
static void allowExternalProcessWindowActivation(int pid=-1)
Allows a window from another process to raise and activate itself.
Definition: kwindowsystem_mac.cpp:622
KAboutData::programName
QString programName() const
KConfigGroup
KConfig
KWallet::Wallet::users
static QStringList users(const QString &wallet)
List the applications that are using the wallet wallet.
Definition: kwallet.cpp:583
KWallet::Wallet::Path
Definition: kwallet.h:135
kwallet.h
KWallet::Wallet::readMapList
int readMapList(const QString &key, QMap< QString, QMap< QString, QString > > &value)
Read the map entry key from the current folder.
Definition: kwallet.cpp:1198
KWallet::Wallet::createFolder
virtual bool createFolder(const QString &f)
Created the folder f.
Definition: kwallet.cpp:849
KWallet::Wallet::sync
virtual int sync()
This syncs the wallet file on disk with what is in memory.
Definition: kwallet.cpp:605
KWallet::Wallet::closeWallet
static int closeWallet(const QString &name, bool force)
Close the wallet name.
Definition: kwallet.cpp:403
KWallet::Wallet::folderList
virtual QStringList folderList()
Obtain the list of all folders contained in the wallet.
Definition: kwallet.cpp:727
KComponentData::isValid
bool isValid() const
KGlobal::mainComponent
const KComponentData & mainComponent()
KGlobal::hasMainComponent
bool hasMainComponent()
KWallet::Wallet::keyDoesNotExist
static bool keyDoesNotExist(const QString &wallet, const QString &folder, const QString &key)
Determine if an entry in a folder does not exist in a wallet.
Definition: kwallet.cpp:1632
StringStringMap
QMap< QString, QString > StringStringMap
Definition: kwallet_mac.cpp:46
kwindowsystem.h
KWallet::Wallet::deleteWallet
static int deleteWallet(const QString &name)
Delete the wallet name.
Definition: kwallet.cpp:426
QString::fromLatin1
QString fromLatin1(const char *str, int size)
QMap::insert
iterator insert(const Key &key, const T &value)
KWallet::registerTypes
static void registerTypes()
Definition: kwallet.cpp:91
kaboutdata.h
KSS_ATTR_WALLETTYPE
#define KSS_ATTR_WALLETTYPE
Definition: kwallet.h:47
kcomponentdata.h
KSharedConfig::openConfig
static KSharedConfig::Ptr openConfig(const QString &fileName=QString(), OpenFlags mode=FullConfig, const char *resourceType="config")
KWallet::s_kwalletdServiceName
static const char s_kwalletdServiceName[]
Definition: kwallet.cpp:241
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
KWallet::Wallet::currentFolder
virtual const QString & currentFolder() const
Determine the current working folder in the wallet.
Definition: kwallet.cpp:968
QDBusReply::error
const QDBusError & error()
QExplicitlySharedDataPointer
QString::data
QChar * data()
QString::arg
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
KConfigGroup::readEntry
T readEntry(const QString &key, const T &aDefault) const
KJob
KWallet::Wallet::writeEntry
virtual int writeEntry(const QString &key, const QByteArray &value, EntryType entryType)
Write key = value as a binary entry to the current folder.
Definition: kwallet.cpp:1308
KWallet::Wallet::EntryType
EntryType
Definition: kwallet.h:80
KComponentData
KWallet::Wallet::isOpen
virtual bool isOpen() const
Determine if the current wallet is open, and is a valid wallet handle.
Definition: kwallet.cpp:666
KWallet::Wallet::folderDoesNotExist
static bool folderDoesNotExist(const QString &wallet, const QString &folder)
Determine if a folder does not exist in a wallet.
Definition: kwallet.cpp:1603
kconfiggroup.h
QDBusServiceWatcher
KWallet::Wallet::writeMap
virtual int writeMap(const QString &key, const QMap< QString, QString > &value)
Write key = value as a map to the current folder.
Definition: kwallet.cpp:1358
QMap::value
const T value(const Key &key) const
QTimer::singleShot
singleShot
KWallet::Wallet::Password
Definition: kwallet.h:80
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:24:00 by doxygen 1.8.7 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 API Reference

Skip menu "kdelibs 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

Search



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