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

KDEUI

kwallet.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE project
00002  *
00003  * Copyright (C) 2002-2004 George Staikos <staikos@kde.org>
00004  * Copyright (C) 2008 Michael Leupold <lemma@confuego.org>
00005  * Copyright (C) 2011 Valentin Rusu <kde@rusu.info>
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Library General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Library General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Library General Public License
00018  * along with this library; see the file COPYING.LIB.  If not, write to
00019  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00020  * Boston, MA 02110-1301, USA.
00021  */
00022 
00023 #include "kwallet.h"
00024 #include "config-kwallet.h"
00025 
00026 #include <QtGui/QApplication>
00027 #include <QtCore/QPointer>
00028 #include <QtGui/QWidget>
00029 #include <QtDBus/QtDBus>
00030 #include <ktoolinvocation.h>
00031 
00032 #include <assert.h>
00033 #include <kcomponentdata.h>
00034 #include <kconfiggroup.h>
00035 #include <kdebug.h>
00036 #include <kdeversion.h>
00037 #include <kglobal.h>
00038 #include <kaboutdata.h>
00039 #include <ksharedconfig.h>
00040 #include <kwindowsystem.h>
00041 
00042 #ifdef HAVE_KSECRETSSERVICE
00043 #include "ksecretsservice/ksecretsservicecollection.h"
00044 #endif 
00045 
00046 #include "kwallet_interface.h"
00047 
00048 #ifdef HAVE_KSECRETSSERVICE
00049 typedef QMap<QString, KSecretsService::StringStringMap> StringToStringStringMapMap;
00050 Q_DECLARE_METATYPE(StringToStringStringMapMap)
00051 #endif
00052 typedef QMap<QString, QByteArray> StringByteArrayMap;
00053 Q_DECLARE_METATYPE(StringByteArrayMap)
00054 
00055 namespace KWallet
00056 {
00057 
00058 class KWalletDLauncher
00059 {
00060 public:
00061     KWalletDLauncher();
00062     ~KWalletDLauncher();
00063     org::kde::KWallet &getInterface();
00064 
00065     // this static variable is used below to switch between old KWallet
00066     // infrastructure and the new one which is built on top of the new
00067     // KSecretsService infrastructure. It's value can be changed via the 
00068     // the Wallet configuration module in System Settings
00069     bool m_useKSecretsService;
00070     org::kde::KWallet *m_wallet;
00071     KConfigGroup m_cgroup;
00072 };
00073 
00074 K_GLOBAL_STATIC(KWalletDLauncher, walletLauncher)
00075 
00076 static QString appid()
00077 {
00078     if (KGlobal::hasMainComponent()) {
00079         KComponentData cData = KGlobal::mainComponent();
00080         if (cData.isValid()) {
00081             const KAboutData* aboutData = cData.aboutData();
00082             if (aboutData) {
00083                 return aboutData->programName();
00084             }
00085             return cData.componentName();
00086         }
00087     }
00088     return qApp->applicationName();
00089 }
00090 
00091 static void registerTypes()
00092 {
00093     static bool registered = false;
00094     if (!registered) {
00095 #ifdef HAVE_KSECRETSSERVICE
00096         qDBusRegisterMetaType<KSecretsService::StringStringMap>();
00097         qDBusRegisterMetaType<StringToStringStringMapMap>();
00098 #endif
00099         qDBusRegisterMetaType<StringByteArrayMap>();
00100         registered = true;
00101     }
00102 }
00103 
00104 bool Wallet::isUsingKSecretsService()
00105 {
00106     return walletLauncher->m_useKSecretsService;
00107 }
00108 
00109 const QString Wallet::LocalWallet() {
00110     // NOTE: This method stays unchanged for KSecretsService
00111     KConfigGroup cfg(KSharedConfig::openConfig("kwalletrc")->group("Wallet"));
00112     if (!cfg.readEntry("Use One Wallet", true)) {
00113         QString tmp = cfg.readEntry("Local Wallet", "localwallet");
00114         if (tmp.isEmpty()) {
00115             return "localwallet";
00116         }
00117         return tmp;
00118     }
00119 
00120     QString tmp = cfg.readEntry("Default Wallet", "kdewallet");
00121     if (tmp.isEmpty()) {
00122         return "kdewallet";
00123     }
00124     return tmp;
00125 }
00126 
00127 const QString Wallet::NetworkWallet() {
00128     // NOTE: This method stays unchanged for KSecretsService
00129     KConfigGroup cfg(KSharedConfig::openConfig("kwalletrc")->group("Wallet"));
00130 
00131     QString tmp = cfg.readEntry("Default Wallet", "kdewallet");
00132     if (tmp.isEmpty()) {
00133         return "kdewallet";
00134     }
00135     return tmp;
00136 }
00137 
00138 const QString Wallet::PasswordFolder() {
00139     return "Passwords";
00140 }
00141 
00142 const QString Wallet::FormDataFolder() {
00143     return "Form Data";
00144 }
00145 
00146 class Wallet::WalletPrivate
00147 {
00148 public:
00149     WalletPrivate(Wallet *wallet, int h, const QString &n)
00150      : q(wallet), name(n), handle(h)
00151 #ifdef HAVE_KSECRETSSERVICE
00152      , secretsCollection(0)
00153 #endif
00154     {}
00155 
00156     void walletServiceUnregistered();
00157 
00158 #ifdef HAVE_KSECRETSSERVICE
00159     template <typename T> 
00160     int writeEntry( const QString& key, const T &value, Wallet::EntryType entryType ) {
00161         int rc = -1;
00162         KSecretsService::Secret secret;
00163         secret.setValue( QVariant::fromValue<T>(value) );
00164 
00165         KSecretsService::StringStringMap attrs;
00166         attrs[KSS_ATTR_ENTRYFOLDER] = folder;
00167         attrs[KSS_ATTR_WALLETTYPE] = QString("%1").arg((int)entryType);
00168         KSecretsService::CreateCollectionItemJob *createItemJob = secretsCollection->createItem( key, attrs, secret );
00169 
00170         if ( !createItemJob->exec() ) {
00171             kDebug(285) << "Cannot execute CreateCollectionItemJob : " << createItemJob->errorString();
00172         }
00173         rc = createItemJob->error();
00174         return rc;
00175     }
00176 
00177     QExplicitlySharedDataPointer<KSecretsService::SecretItem> findItem( const QString& key ) const;
00178     template <typename T> int readEntry( const QString& key, T& value ) const;
00179     bool readSecret( const QString& key, KSecretsService::Secret& value ) const;
00180     
00181     template <typename V>
00182     int forEachItemThatMatches( const QString &key, V verb ) {
00183         int rc = -1;
00184         KSecretsService::StringStringMap attrs;
00185         attrs[KSS_ATTR_ENTRYFOLDER] = folder;
00186         KSecretsService::SearchCollectionItemsJob *searchItemsJob = secretsCollection->searchItems(attrs);
00187         if ( searchItemsJob->exec() ) {
00188             QRegExp re(key, Qt::CaseSensitive, QRegExp::Wildcard);
00189             foreach( KSecretsService::SearchCollectionItemsJob::Item item , searchItemsJob->items() ) {
00190                 KSecretsService::ReadItemPropertyJob *readLabelJob = item->label();
00191                 if ( readLabelJob->exec() ) {
00192                     QString label = readLabelJob->propertyValue().toString();
00193                     if ( re.exactMatch( label ) ) {
00194                         if ( verb( this, label, item.data() ) ) {
00195                             rc = 0; // one successfull iteration already produced results, so success return
00196                         }
00197                     }
00198                 }
00199                 else {
00200                     kDebug(285) << "Cannot execute ReadItemPropertyJob " << readLabelJob->errorString();
00201                 }
00202             }
00203         }
00204         else {
00205             kDebug(285) << "Cannot execute KSecretsService::SearchCollectionItemsJob " << searchItemsJob->errorString();
00206         }
00207         return rc;
00208     }
00209 
00210     void createDefaultFolders();
00211 
00212     struct InsertIntoEntryList;
00213     struct InsertIntoMapList;
00214     struct InsertIntoPasswordList;
00215 
00216     KSecretsService::Collection *secretsCollection;
00217 #endif // HAVE_KSECRETSSERVICE
00218 
00219     Wallet *q;
00220     QString name;
00221     QString folder;
00222     int handle;
00223     int transactionId;
00224     QPointer<QEventLoop> loop;
00225 };
00226 
00227 #ifdef HAVE_KSECRETSSERVICE
00228 void Wallet::WalletPrivate::createDefaultFolders()
00229 {
00230 // NOTE: KWalletManager expects newly created wallets to have two default folders
00231 //     b->createFolder(KWallet::Wallet::PasswordFolder());
00232 //     b->createFolder(KWallet::Wallet::FormDataFolder());
00233     QString strDummy("");
00234     folder = PasswordFolder();
00235     writeEntry( PasswordFolder(), strDummy, KWallet::Wallet::Unknown );
00236     
00237     folder = FormDataFolder();
00238     writeEntry( FormDataFolder(), strDummy, KWallet::Wallet::Unknown );
00239 }
00240 #endif // HAVE_KSECRETSSERVICE
00241 
00242 static const char s_kwalletdServiceName[] = "org.kde.kwalletd";
00243 
00244 Wallet::Wallet(int handle, const QString& name)
00245     : QObject(0L), d(new WalletPrivate(this, handle, name))
00246 {
00247     if (walletLauncher->m_useKSecretsService) {
00248         // see openWallet for initialization code; this constructor does not have any code
00249     }
00250     else {
00251         QDBusServiceWatcher *watcher = new QDBusServiceWatcher(QString::fromLatin1(s_kwalletdServiceName), QDBusConnection::sessionBus(),
00252                                                             QDBusServiceWatcher::WatchForUnregistration, this);
00253         connect(watcher, SIGNAL(serviceUnregistered(QString)),
00254                 this, SLOT(walletServiceUnregistered()));
00255 
00256         connect(&walletLauncher->getInterface(), SIGNAL(walletClosed(int)), SLOT(slotWalletClosed(int)));
00257         connect(&walletLauncher->getInterface(), SIGNAL(folderListUpdated(QString)), SLOT(slotFolderListUpdated(QString)));
00258         connect(&walletLauncher->getInterface(), SIGNAL(folderUpdated(QString,QString)), SLOT(slotFolderUpdated(QString,QString)));
00259         connect(&walletLauncher->getInterface(), SIGNAL(applicationDisconnected(QString,QString)), SLOT(slotApplicationDisconnected(QString,QString)));
00260 
00261         // Verify that the wallet is still open
00262         if (d->handle != -1) {
00263             QDBusReply<bool> r = walletLauncher->getInterface().isOpen(d->handle);
00264             if (r.isValid() && !r) {
00265                 d->handle = -1;
00266                 d->name.clear();
00267             }
00268         }
00269     }
00270 }
00271 
00272 
00273 Wallet::~Wallet() {
00274 #ifdef HAVE_KSECRETSSERVICE
00275     if (walletLauncher->m_useKSecretsService) {
00276         d->folder.clear();
00277         d->name.clear();
00278         delete d->secretsCollection;
00279     }
00280     else {
00281 #endif
00282         if (d->handle != -1) {
00283             if (!walletLauncher.isDestroyed()) {
00284                 walletLauncher->getInterface().close(d->handle, false, appid());
00285             } else {
00286                 kDebug(285) << "Problem with static destruction sequence."
00287                             "Destroy any static Wallet before the event-loop exits.";
00288             }
00289             d->handle = -1;
00290             d->folder.clear();
00291             d->name.clear();
00292         }
00293 #ifdef HAVE_KSECRETSSERVICE
00294     }
00295 #endif
00296     delete d;
00297 }
00298 
00299 
00300 QStringList Wallet::walletList() {
00301     QStringList result;
00302 #ifdef HAVE_KSECRETSSERVICE
00303     if (walletLauncher->m_useKSecretsService) {
00304         KSecretsService::ListCollectionsJob *listJob = KSecretsService::Collection::listCollections();
00305         if ( listJob->exec() ) {
00306             result = listJob->collections();
00307         }
00308         else {
00309             kDebug(285) << "Cannot execute ListCollectionsJob: " << listJob->errorString();
00310         }
00311     }
00312     else {
00313 #endif
00314         QDBusReply<QStringList> r = walletLauncher->getInterface().wallets();
00315 
00316         if (!r.isValid())
00317         {
00318                 kDebug(285) << "Invalid DBus reply: " << r.error();
00319         }
00320         else
00321             result = r;
00322 #ifdef HAVE_KSECRETSSERVICE
00323     }
00324 #endif
00325     return result;
00326 }
00327 
00328 
00329 void Wallet::changePassword(const QString& name, WId w) {
00330     if( w == 0 )
00331         kDebug(285) << "Pass a valid window to KWallet::Wallet::changePassword().";
00332 
00333     // Make sure the password prompt window will be visible and activated
00334     KWindowSystem::allowExternalProcessWindowActivation();
00335 #ifdef HAVE_KSECRETSSERVICE
00336     if (walletLauncher->m_useKSecretsService) {
00337         KSecretsService::Collection *coll = KSecretsService::Collection::findCollection( name );
00338         KSecretsService::ChangeCollectionPasswordJob* changePwdJob = coll->changePassword();
00339         if ( !changePwdJob->exec() ) {
00340             kDebug(285) << "Cannot execute change password job: " << changePwdJob->errorString();
00341         }
00342         coll->deleteLater();
00343     }
00344     else {
00345 #endif
00346         walletLauncher->getInterface().changePassword(name, (qlonglong)w, appid());
00347 #ifdef HAVE_KSECRETSSERVICE
00348     }
00349 #endif
00350 }
00351 
00352 
00353 bool Wallet::isEnabled() {
00354 #ifdef HAVE_KSECRETSSERVICE
00355     if (walletLauncher->m_useKSecretsService) {
00356         return walletLauncher->m_cgroup.readEntry("Enabled", true);
00357     }
00358     else {
00359 #endif
00360         QDBusReply<bool> r = walletLauncher->getInterface().isEnabled();
00361 
00362         if (!r.isValid())
00363         {
00364                 kDebug(285) << "Invalid DBus reply: " << r.error();
00365                 return false;
00366         }
00367         else
00368             return r;
00369 #ifdef HAVE_KSECRETSSERVICE
00370     }
00371 #endif
00372 }
00373 
00374 
00375 bool Wallet::isOpen(const QString& name) {
00376 #ifdef HAVE_KSECRETSSERVICE
00377     if (walletLauncher->m_useKSecretsService) {
00378         KSecretsService::Collection *coll = KSecretsService::Collection::findCollection( name, KSecretsService::Collection::OpenOnly );
00379         KSecretsService::ReadCollectionPropertyJob *readLocked = coll->isLocked();
00380         if ( readLocked->exec() ) {
00381             return !readLocked->propertyValue().toBool();
00382         }
00383         else {
00384             kDebug() << "ReadLocked job failed";
00385             return false;
00386         }
00387     }
00388     else {
00389 #endif
00390         QDBusReply<bool> r = walletLauncher->getInterface().isOpen(name);
00391 
00392         if (!r.isValid())
00393         {
00394                 kDebug(285) << "Invalid DBus reply: " << r.error();
00395                 return false;
00396         }
00397         else
00398             return r;
00399 #ifdef HAVE_KSECRETSSERVICE
00400     }
00401 #endif
00402 }
00403 
00404 int Wallet::closeWallet(const QString& name, bool force) {
00405 #ifdef HAVE_KSECRETSSERVICE
00406     if (walletLauncher->m_useKSecretsService) {
00407         kDebug(285) << "Wallet::closeWallet NOOP";
00408         return 0;
00409     }
00410     else {
00411 #endif
00412         QDBusReply<int> r = walletLauncher->getInterface().close(name, force);
00413 
00414         if (!r.isValid())
00415         {
00416                 kDebug(285) << "Invalid DBus reply: " << r.error();
00417                 return -1;
00418         }
00419         else
00420             return r;
00421 #ifdef HAVE_KSECRETSSERVICE
00422     }
00423 #endif
00424 }
00425 
00426 
00427 int Wallet::deleteWallet(const QString& name) {
00428 #ifdef HAVE_KSECRETSSERVICE
00429     if (walletLauncher->m_useKSecretsService) {
00430         KSecretsService::Collection *coll = KSecretsService::Collection::findCollection(name, KSecretsService::Collection::OpenOnly);
00431         KJob *deleteJob = coll->deleteCollection();
00432         if (!deleteJob->exec()) {
00433             kDebug(285) << "Cannot execute delete job " << deleteJob->errorString();
00434         }
00435         return deleteJob->error();
00436     }
00437     else {
00438 #endif
00439         QDBusReply<int> r = walletLauncher->getInterface().deleteWallet(name);
00440 
00441         if (!r.isValid())
00442         {
00443                 kDebug(285) << "Invalid DBus reply: " << r.error();
00444                 return -1;
00445         }
00446         else
00447             return r;
00448 #ifdef HAVE_KSECRETSSERVICE
00449     }
00450 #endif
00451 }
00452 
00453 Wallet *Wallet::openWallet(const QString& name, WId w, OpenType ot) {
00454     if( w == 0 )
00455         kDebug(285) << "Pass a valid window to KWallet::Wallet::openWallet().";
00456 
00457 #ifdef HAVE_KSECRETSSERVICE
00458     if (walletLauncher->m_useKSecretsService) {
00459         Wallet *wallet = new Wallet(-1, name);
00460         // FIXME: should we specify CreateCollection or OpenOnly here?
00461         wallet->d->secretsCollection = KSecretsService::Collection::findCollection(name, KSecretsService::Collection::CreateCollection, QVariantMap(), w);
00462         connect( wallet->d->secretsCollection, SIGNAL(statusChanged(int)), wallet, SLOT(slotCollectionStatusChanged(int)) );
00463         connect( wallet->d->secretsCollection, SIGNAL(deleted()), wallet, SLOT(slotCollectionDeleted()) );
00464         if ( ot == Synchronous ) {
00465            kDebug() << "WARNING openWallet OpenType=Synchronous requested";
00466            // TODO: not sure what to do with in this case; however, all other KSecretsService API methods are already
00467            // async and will perform sync inside this API because of it's design
00468         }
00469         return wallet;
00470     }
00471     else {
00472 #endif
00473         Wallet *wallet = new Wallet(-1, name);
00474 
00475         // connect the daemon's opened signal to the slot filtering the
00476         // signals we need
00477         connect(&walletLauncher->getInterface(), SIGNAL(walletAsyncOpened(int,int)),
00478                 wallet, SLOT(walletAsyncOpened(int,int)));
00479 
00480         // Use an eventloop for synchronous calls
00481         QEventLoop loop;
00482         if (ot == Synchronous || ot == Path) {
00483             connect(wallet, SIGNAL(walletOpened(bool)), &loop, SLOT(quit()));
00484         }
00485 
00486         // Make sure the password prompt window will be visible and activated
00487         KWindowSystem::allowExternalProcessWindowActivation();
00488 
00489         // do the call
00490         QDBusReply<int> r;
00491         if (ot == Synchronous || ot == Asynchronous) {
00492             r = walletLauncher->getInterface().openAsync(name, (qlonglong)w, appid(), true);
00493         } else if (ot == Path) {
00494             r = walletLauncher->getInterface().openPathAsync(name, (qlonglong)w, appid(), true);
00495         } else {
00496             delete wallet;
00497             return 0;
00498         }
00499         // error communicating with the daemon (maybe not running)
00500         if (!r.isValid()) {
00501             kDebug(285) << "Invalid DBus reply: " << r.error();
00502             delete wallet;
00503             return 0;
00504         }
00505         wallet->d->transactionId = r.value();
00506 
00507         if (ot == Synchronous || ot == Path) {
00508             // check for an immediate error
00509             if (wallet->d->transactionId < 0) {
00510                 delete wallet;
00511                 wallet = 0;
00512             } else {
00513                 // wait for the daemon's reply
00514                 // store a pointer to the event loop so it can be quit in error case
00515                 wallet->d->loop = &loop;
00516                 loop.exec();
00517                 if (wallet->d->handle < 0) {
00518                     delete wallet;
00519                     return 0;
00520                 }
00521             }
00522         } else if (ot == Asynchronous) {
00523             if (wallet->d->transactionId < 0) {
00524                 QTimer::singleShot(0, wallet, SLOT(emitWalletAsyncOpenError()));
00525                 // client code is responsible for deleting the wallet
00526             }
00527         }
00528 
00529         return wallet;
00530 #ifdef HAVE_KSECRETSSERVICE
00531     }
00532 #endif
00533 }
00534 
00535 void Wallet::slotCollectionStatusChanged(int status)
00536 {
00537 #ifdef HAVE_KSECRETSSERVICE
00538     KSecretsService::Collection::Status collStatus = (KSecretsService::Collection::Status)status;
00539     switch ( collStatus ) {
00540         case KSecretsService::Collection::NewlyCreated:
00541             d->createDefaultFolders();
00542             // fall through
00543         case KSecretsService::Collection::FoundExisting:
00544             emitWalletOpened();
00545             break;
00546         case KSecretsService::Collection::Deleted:
00547         case KSecretsService::Collection::Invalid:
00548         case KSecretsService::Collection::Pending:
00549             // nothing to do
00550             break;
00551         case KSecretsService::Collection::NotFound:
00552             emitWalletAsyncOpenError();
00553             break;
00554     }
00555 #endif
00556 }
00557 
00558 void Wallet::slotCollectionDeleted()
00559 {
00560     d->folder.clear();
00561     d->name.clear();
00562     emit walletClosed();
00563 }
00564 
00565 bool Wallet::disconnectApplication(const QString& wallet, const QString& app) {
00566 #ifdef HAVE_KSECRETSSERVICE
00567     if (walletLauncher->m_useKSecretsService) {
00568         kDebug() << "Wallet::disconnectApplication NOOP";
00569         return true;
00570     }
00571     else {
00572 #endif
00573         QDBusReply<bool> r = walletLauncher->getInterface().disconnectApplication(wallet, app);
00574 
00575         if (!r.isValid())
00576         {
00577                 kDebug(285) << "Invalid DBus reply: " << r.error();
00578                 return false;
00579         }
00580         else
00581             return r;
00582 #ifdef HAVE_KSECRETSSERVICE
00583     }
00584 #endif
00585 }
00586 
00587 
00588 QStringList Wallet::users(const QString& name) {
00589 #ifdef HAVE_KSECRETSSERVICE
00590     if (walletLauncher->m_useKSecretsService) {
00591         kDebug() << "KSecretsService does not handle users list";
00592         return QStringList();
00593     }
00594     else {
00595 #endif
00596         QDBusReply<QStringList> r = walletLauncher->getInterface().users(name);
00597         if (!r.isValid())
00598         {
00599                 kDebug(285) << "Invalid DBus reply: " << r.error();
00600                 return QStringList();
00601         }
00602         else
00603             return r;
00604 #ifdef HAVE_KSECRETSSERVICE
00605     }
00606 #endif
00607 }
00608 
00609 
00610 int Wallet::sync() {
00611 #ifdef HAVE_KSECRETSSERVICE
00612     if (walletLauncher->m_useKSecretsService) {
00613         // NOOP with KSecretsService
00614     }
00615     else {
00616 #endif
00617         if (d->handle == -1) {
00618             return -1;
00619         }
00620 
00621         walletLauncher->getInterface().sync(d->handle, appid());
00622 #ifdef HAVE_KSECRETSSERVICE
00623     }
00624 #endif
00625     return 0;
00626 }
00627 
00628 
00629 int Wallet::lockWallet() {
00630 #ifdef HAVE_KSECRETSSERVICE
00631     if (walletLauncher->m_useKSecretsService) {
00632         KSecretsService::CollectionLockJob *lockJob = d->secretsCollection->lock();
00633         if (lockJob->exec()) {
00634             d->folder.clear();
00635             d->name.clear();
00636         }
00637         else {
00638             kDebug(285) << "Cannot execute KSecretsService::CollectionLockJob : " << lockJob->errorString();
00639             return -1;
00640         }
00641         return lockJob->error();
00642     }
00643     else {
00644 #endif
00645         if (d->handle == -1) {
00646             return -1;
00647         }
00648 
00649         QDBusReply<int> r = walletLauncher->getInterface().close(d->handle, true, appid());
00650         d->handle = -1;
00651         d->folder.clear();
00652         d->name.clear();
00653         if (r.isValid()) {
00654             return r;
00655         }
00656         else {
00657             kDebug(285) << "Invalid DBus reply: " << r.error();
00658             return -1;
00659         }
00660 #ifdef HAVE_KSECRETSSERVICE
00661     }
00662 #endif
00663 }
00664 
00665 
00666 const QString& Wallet::walletName() const {
00667     return d->name;
00668 }
00669 
00670 
00671 bool Wallet::isOpen() const {
00672 #ifdef HAVE_KSECRETSSERVICE
00673     if (walletLauncher->m_useKSecretsService) {
00674         return !d->secretsCollection->isLocked();
00675     }
00676     else {
00677 #endif
00678         return d->handle != -1;
00679 #ifdef HAVE_KSECRETSSERVICE
00680     }
00681 #endif
00682 }
00683 
00684 
00685 void Wallet::requestChangePassword(WId w) {
00686     if( w == 0 )
00687         kDebug(285) << "Pass a valid window to KWallet::Wallet::requestChangePassword().";
00688 
00689 #ifdef HAVE_KSECRETSSERVICE
00690     if (walletLauncher->m_useKSecretsService) {
00691         KSecretsService::ChangeCollectionPasswordJob *changePwdJob = d->secretsCollection->changePassword();
00692         if (!changePwdJob->exec()) {
00693             kDebug(285) << "Cannot execute ChangeCollectionPasswordJob : " << changePwdJob->errorString();
00694         }
00695     }
00696     else {
00697 #endif
00698         if (d->handle == -1) {
00699             return;
00700         }
00701 
00702         // Make sure the password prompt window will be visible and activated
00703         KWindowSystem::allowExternalProcessWindowActivation();
00704 
00705         walletLauncher->getInterface().changePassword(d->name, (qlonglong)w, appid());
00706 #ifdef HAVE_KSECRETSSERVICE
00707     }
00708 #endif
00709 }
00710 
00711 
00712 void Wallet::slotWalletClosed(int handle) {
00713 #ifdef HAVE_KSECRETSSERVICE
00714     if (walletLauncher->m_useKSecretsService) {
00715         // TODO: implement this
00716         Q_ASSERT(0);
00717     }
00718     else {
00719 #endif
00720         if (d->handle == handle) {
00721             d->handle = -1;
00722             d->folder.clear();
00723             d->name.clear();
00724             emit walletClosed();
00725         }
00726 #ifdef HAVE_KSECRETSSERVICE
00727     }
00728 #endif
00729 }
00730 
00731 
00732 QStringList Wallet::folderList() {
00733 #ifdef HAVE_KSECRETSSERVICE
00734     if (walletLauncher->m_useKSecretsService) {
00735         QStringList result;
00736         
00737         KSecretsService::StringStringMap attrs;
00738         attrs[KSS_ATTR_ENTRYFOLDER] = ""; // search for items having this attribute no matter what value it has
00739         KSecretsService::SearchCollectionItemsJob *searchJob = d->secretsCollection->searchItems(attrs);
00740         
00741         if (searchJob->exec()) {
00742             KSecretsService::ReadCollectionItemsJob::ItemList itemList = searchJob->items();
00743             foreach( const KSecretsService::ReadCollectionItemsJob::Item &item, itemList ) {
00744                 KSecretsService::ReadItemPropertyJob *readAttrsJob = item->attributes();
00745                 if (readAttrsJob->exec()) {
00746                     KSecretsService::StringStringMap attrs = readAttrsJob->propertyValue().value<KSecretsService::StringStringMap>();
00747                     const QString folder = attrs[KSS_ATTR_ENTRYFOLDER];
00748                     if (!folder.isEmpty() && !result.contains(folder)) {
00749                         result.append(folder);
00750                     }
00751                 }
00752                 else {
00753                     kDebug(285) << "Cannot read item attributes : " << readAttrsJob->errorString();
00754                 }
00755             }
00756         }
00757         else {
00758             kDebug(285) << "Cannot execute ReadCollectionItemsJob : " << searchJob->errorString();
00759         }
00760         return result;
00761     }
00762     else {
00763 #endif        
00764         if (d->handle == -1) {
00765             return QStringList();
00766         }
00767 
00768         QDBusReply<QStringList> r = walletLauncher->getInterface().folderList(d->handle, appid());
00769         if (!r.isValid())
00770         {
00771                 kDebug(285) << "Invalid DBus reply: " << r.error();
00772                 return QStringList();
00773         }
00774         else
00775             return r;
00776 #ifdef HAVE_KSECRETSSERVICE
00777     }
00778 #endif
00779 }
00780 
00781 
00782 QStringList Wallet::entryList() {
00783 #ifdef HAVE_KSECRETSSERVICE
00784     if (walletLauncher->m_useKSecretsService) {
00785         QStringList result;
00786         KSecretsService::StringStringMap attrs;
00787         attrs[KSS_ATTR_ENTRYFOLDER] = d->folder;
00788         KSecretsService::SearchCollectionItemsJob *readItemsJob = d->secretsCollection->searchItems( attrs );
00789         if ( readItemsJob->exec() ) {
00790             foreach( KSecretsService::SearchCollectionItemsJob::Item item, readItemsJob->items() ) {
00791                 KSecretsService::ReadItemPropertyJob *readLabelJob = item->label();
00792                 if ( readLabelJob->exec() ) {
00793                     result.append( readLabelJob->propertyValue().toString() );
00794                 }
00795                 else {
00796                     kDebug(285) << "Cannot execute readLabelJob" << readItemsJob->errorString();
00797                 }
00798             }
00799         }
00800         else {
00801             kDebug(285) << "Cannot execute readItemsJob" << readItemsJob->errorString();
00802         }
00803         return result;
00804     }
00805     else {
00806 #endif
00807         if (d->handle == -1) {
00808             return QStringList();
00809         }
00810 
00811         QDBusReply<QStringList> r = walletLauncher->getInterface().entryList(d->handle, d->folder, appid());
00812         if (!r.isValid())
00813         {
00814                 kDebug(285) << "Invalid DBus reply: " << r.error();
00815                 return QStringList();
00816         }
00817         else
00818             return r;
00819 #ifdef HAVE_KSECRETSSERVICE
00820     }
00821 #endif
00822 }
00823 
00824 
00825 bool Wallet::hasFolder(const QString& f) {
00826 #ifdef HAVE_KSECRETSSERVICE
00827     if (walletLauncher->m_useKSecretsService) {
00828         // FIXME: well, this is not the best implementation, but it's done quickly :)
00829         // the best way would be to searchItems with the attribute label having the value f
00830         // doing that would reduce DBus traffic. But KWallet API wille not last.
00831         QStringList folders = folderList();
00832         return folders.contains(f);
00833     }
00834     else {
00835 #endif
00836         if (d->handle == -1) {
00837             return false;
00838         }
00839 
00840         QDBusReply<bool> r = walletLauncher->getInterface().hasFolder(d->handle, f, appid());
00841         if (!r.isValid())
00842         {
00843                 kDebug(285) << "Invalid DBus reply: " << r.error();
00844                 return false;
00845         }
00846         else
00847             return r;
00848 #ifdef HAVE_KSECRETSSERVICE
00849     }
00850 #endif
00851 }
00852 
00853 
00854 bool Wallet::createFolder(const QString& f) {
00855 #ifdef HAVE_KSECRETSSERVICE
00856     if (walletLauncher->m_useKSecretsService) {
00857         QString strDummy("");
00858         d->folder = f;
00859         d->writeEntry( f, strDummy, KWallet::Wallet::Unknown );
00860         return true;
00861     }
00862     else {
00863 #endif
00864         if (d->handle == -1) {
00865             return false;
00866         }
00867 
00868         if (!hasFolder(f)) {
00869             QDBusReply<bool> r = walletLauncher->getInterface().createFolder(d->handle, f, appid());
00870 
00871             if (!r.isValid())
00872             {
00873                     kDebug(285) << "Invalid DBus reply: " << r.error();
00874                     return false;
00875             }
00876             else
00877                 return r;
00878         }
00879 
00880         return true;                // folder already exists
00881 #ifdef HAVE_KSECRETSSERVICE
00882     }
00883 #endif
00884 }
00885 
00886 
00887 bool Wallet::setFolder(const QString& f) {
00888     bool rc = false;
00889 
00890 #ifdef HAVE_KSECRETSSERVICE
00891     if (walletLauncher->m_useKSecretsService) {
00892         if (hasFolder(f)) {
00893             d->folder = f;
00894             rc = true;
00895         }
00896     }
00897     else {
00898 #endif
00899         if (d->handle == -1) {
00900             return rc;
00901         }
00902 
00903         // Don't do this - the folder could have disappeared?
00904     #if 0
00905         if (f == d->folder) {
00906             return true;
00907         }
00908     #endif
00909 
00910         if (hasFolder(f)) {
00911             d->folder = f;
00912             rc = true;
00913         }
00914 #ifdef HAVE_KSECRETSSERVICE
00915     }
00916 #endif
00917 
00918     return rc;
00919 }
00920 
00921 
00922 bool Wallet::removeFolder(const QString& f) {
00923 #ifdef HAVE_KSECRETSSERVICE
00924     if (walletLauncher->m_useKSecretsService) {
00925         bool result = false;
00926         // search for all items having the folder f then delete them
00927         KSecretsService::StringStringMap attrs;
00928         attrs[KSS_ATTR_ENTRYFOLDER] = f;
00929         KSecretsService::SearchCollectionItemsJob *searchJob = d->secretsCollection->searchItems(attrs);
00930         if (searchJob->exec()) {
00931             KSecretsService::SearchCollectionItemsJob::ItemList itemList = searchJob->items();
00932             if ( !itemList.isEmpty() ) {
00933                 result = true;
00934                 foreach( const KSecretsService::SearchCollectionItemsJob::Item &item, itemList ) {
00935                     KSecretsService::SecretItemDeleteJob *deleteJob = item->deleteItem();
00936                     if (!deleteJob->exec()) {
00937                         kDebug(285) << "Cannot delete item : " << deleteJob->errorString();
00938                         result = false;
00939                     }
00940                     result &= true;
00941                 }
00942             }
00943         }
00944         else {
00945             kDebug(285) << "Cannot execute KSecretsService::SearchCollectionItemsJob : " << searchJob->errorString();
00946         }
00947         return result;
00948     }
00949     else {
00950 #endif
00951         if (d->handle == -1) {
00952             return false;
00953         }
00954 
00955         QDBusReply<bool> r = walletLauncher->getInterface().removeFolder(d->handle, f, appid());
00956         if (d->folder == f) {
00957             setFolder(QString());
00958         }
00959 
00960         if (!r.isValid())
00961         {
00962             kDebug(285) << "Invalid DBus reply: " << r.error();
00963             return false;
00964         }
00965         else
00966             return r;
00967 #ifdef HAVE_KSECRETSSERVICE
00968     }
00969 #endif
00970 }
00971 
00972 
00973 const QString& Wallet::currentFolder() const {
00974     return d->folder;
00975 }
00976 
00977 #ifdef HAVE_KSECRETSSERVICE
00978 QExplicitlySharedDataPointer<KSecretsService::SecretItem> Wallet::WalletPrivate::findItem( const QString& key ) const
00979 {
00980     QExplicitlySharedDataPointer<KSecretsService::SecretItem> result;
00981     KSecretsService::StringStringMap attrs;
00982     attrs[KSS_ATTR_ENTRYFOLDER] = folder;
00983     attrs["Label"] = key;
00984     KSecretsService::SearchCollectionItemsJob *searchJob = secretsCollection->searchItems(attrs);
00985     if (searchJob->exec()) {
00986         KSecretsService::SearchCollectionItemsJob::ItemList itemList = searchJob->items();
00987         if ( !itemList.isEmpty() ) {
00988             result = itemList.first();
00989         }
00990         else {
00991             kDebug(285) << "entry named " << key << " not found in folder " << folder;
00992         }
00993     }
00994     else {
00995         kDebug(285) << "Cannot exec KSecretsService::SearchCollectionItemsJob : " << searchJob->errorString();
00996     }
00997 
00998     return result;
00999 }
01000 
01001 template <typename T>
01002 int Wallet::WalletPrivate::readEntry(const QString& key, T& value) const
01003 {
01004     int rc = -1;
01005     QExplicitlySharedDataPointer<KSecretsService::SecretItem> item = findItem(key);
01006     if ( item ) {
01007         KSecretsService::GetSecretItemSecretJob *readJob = item->getSecret();
01008         if ( readJob->exec() ) {
01009             KSecretsService::Secret theSecret = readJob->secret();
01010             kDebug(285) << "Secret contentType is " << theSecret.contentType();
01011             value = theSecret.value().value<T>();
01012             rc = 0;
01013         }
01014         else {
01015             kDebug(285) << "Cannot exec GetSecretItemSecretJob : " << readJob->errorString();
01016         }
01017     }
01018     return rc;
01019 }
01020 
01021 bool Wallet::WalletPrivate::readSecret(const QString& key, KSecretsService::Secret& value) const
01022 {
01023     bool result = false;
01024     QExplicitlySharedDataPointer<KSecretsService::SecretItem> item = findItem(key);
01025     if ( item ) {
01026         KSecretsService::GetSecretItemSecretJob *readJob = item->getSecret();
01027         if ( readJob->exec() ) {
01028             value = readJob->secret();
01029             result = true;
01030         }
01031         else {
01032             kDebug(285) << "Cannot exec GetSecretItemSecretJob : " << readJob->errorString();
01033         }
01034     }
01035     return result;
01036 }
01037 #endif
01038 
01039 int Wallet::readEntry(const QString& key, QByteArray& value) {
01040     int rc = -1;
01041 
01042 #ifdef HAVE_KSECRETSSERVICE
01043     if (walletLauncher->m_useKSecretsService) {
01044         return d->readEntry<QByteArray>(key, value);
01045     }
01046     else {
01047 #endif
01048         if (d->handle == -1) {
01049             return rc;
01050         }
01051 
01052         QDBusReply<QByteArray> r = walletLauncher->getInterface().readEntry(d->handle, d->folder, key, appid());
01053         if (r.isValid()) {
01054             value = r;
01055             rc = 0;
01056         }
01057 #ifdef HAVE_KSECRETSSERVICE
01058     }
01059 #endif
01060 
01061     return rc;
01062 }
01063 
01064 #ifdef HAVE_KSECRETSSERVICE
01065 struct Wallet::WalletPrivate::InsertIntoEntryList {
01066     InsertIntoEntryList( QMap< QString, QByteArray> &value ) : _value( value ) {}
01067     bool operator() ( Wallet::WalletPrivate*, const QString& label, KSecretsService::SecretItem* item ) {
01068         bool result = false;
01069         KSecretsService::GetSecretItemSecretJob *readSecretJob = item->getSecret();
01070         if ( readSecretJob->exec() ) {
01071             _value.insert( label, readSecretJob->secret().value().toByteArray() );
01072             result = true;
01073         }
01074         else {
01075             kDebug(285) << "Cannot execute GetSecretItemSecretJob " << readSecretJob->errorString();
01076         }
01077         return result;
01078     }
01079     QMap< QString, QByteArray > _value;
01080 };
01081 #endif
01082 
01083 int Wallet::readEntryList(const QString& key, QMap<QString, QByteArray>& value) {
01084 
01085     int rc = -1;
01086 
01087 #ifdef HAVE_KSECRETSSERVICE
01088     if (walletLauncher->m_useKSecretsService) {
01089         rc = d->forEachItemThatMatches( key, WalletPrivate::InsertIntoEntryList( value ) );
01090     }
01091     else {
01092 #endif
01093         registerTypes();
01094         
01095         if (d->handle == -1) {
01096             return rc;
01097         }
01098 
01099         QDBusReply<QVariantMap> r = walletLauncher->getInterface().readEntryList(d->handle, d->folder, key, appid());
01100         if (r.isValid()) {
01101             rc = 0;
01102             // convert <QString, QVariant> to <QString, QByteArray>
01103             const QVariantMap val = r.value();
01104             for( QVariantMap::const_iterator it = val.begin(); it != val.end(); ++it ) {
01105                 value.insert(it.key(), it.value().toByteArray());
01106             }
01107         }
01108 #ifdef HAVE_KSECRETSSERVICE
01109     }
01110 #endif
01111 
01112     return rc;
01113 }
01114 
01115 
01116 int Wallet::renameEntry(const QString& oldName, const QString& newName) {
01117     int rc = -1;
01118 
01119 #ifdef HAVE_KSECRETSSERVICE
01120     if (walletLauncher->m_useKSecretsService) {
01121         QExplicitlySharedDataPointer<KSecretsService::SecretItem> item = d->findItem(oldName);
01122         if (item) {
01123             KSecretsService::WriteItemPropertyJob *writeJob = item->setLabel(newName);
01124             if (!writeJob->exec()) {
01125                 kDebug(285) << "Cannot exec WriteItemPropertyJob : " << writeJob->errorString();
01126             }
01127             rc = writeJob->error();
01128         }
01129         else {
01130             kDebug(285) << "Cannot locate item " << oldName << " in folder " << d->folder;
01131         }
01132     }
01133     else {
01134 #endif
01135         if (d->handle == -1) {
01136             return rc;
01137         }
01138 
01139         QDBusReply<int> r = walletLauncher->getInterface().renameEntry(d->handle, d->folder, oldName, newName, appid());
01140         if (r.isValid()) {
01141             rc = r;
01142         }
01143 #ifdef HAVE_KSECRETSSERVICE
01144     }
01145 #endif
01146 
01147     return rc;
01148 }
01149 
01150 
01151 int Wallet::readMap(const QString& key, QMap<QString,QString>& value) {
01152     int rc = -1;
01153 
01154 #ifdef HAVE_KSECRETSSERVICE
01155     if (walletLauncher->m_useKSecretsService) {
01156         QByteArray ba;
01157         rc = d->readEntry< QByteArray >(key, ba);
01158         if ( rc == 0 && !ba.isEmpty()){
01159             QDataStream ds( &ba, QIODevice::ReadOnly );
01160             ds >> value;
01161         }
01162     }
01163     else {
01164 #endif
01165         registerTypes();
01166 
01167         if (d->handle == -1) {
01168             return rc;
01169         }
01170 
01171         QDBusReply<QByteArray> r = walletLauncher->getInterface().readMap(d->handle, d->folder, key, appid());
01172         if (r.isValid()) {
01173             rc = 0;
01174             QByteArray v = r;
01175             if (!v.isEmpty()) {
01176                 QDataStream ds(&v, QIODevice::ReadOnly);
01177                 ds >> value;
01178             }
01179         }
01180 #ifdef HAVE_KSECRETSSERVICE
01181     }
01182 #endif
01183 
01184     return rc;
01185 }
01186 
01187 #ifdef HAVE_KSECRETSSERVICE
01188 struct Wallet::WalletPrivate::InsertIntoMapList {
01189     InsertIntoMapList( QMap< QString, QMap< QString, QString > > &value ) : _value( value ) {}
01190     bool operator() ( Wallet::WalletPrivate* d, const QString& label, KSecretsService::SecretItem* ) {
01191         bool result = false;
01192         QMap<QString, QString> map;
01193         if ( d->readEntry< QMap< QString, QString> >(label, map) ) {
01194             _value.insert( label, map );
01195             result = true;
01196         }
01197         return result;
01198     }
01199     QMap< QString, QMap< QString, QString> > &_value;
01200 };
01201 #endif
01202 
01203 int Wallet::readMapList(const QString& key, QMap<QString, QMap<QString, QString> >& value) {
01204     int rc = -1;
01205 
01206 #ifdef HAVE_KSECRETSSERVICE
01207     if (walletLauncher->m_useKSecretsService) {
01208         rc = d->forEachItemThatMatches( key, WalletPrivate::InsertIntoMapList( value ) );
01209     }
01210     else {
01211 #endif
01212         registerTypes();
01213 
01214         if (d->handle == -1) {
01215             return rc;
01216         }
01217 
01218         QDBusReply<QVariantMap> r =
01219             walletLauncher->getInterface().readMapList(d->handle, d->folder, key, appid());
01220         if (r.isValid()) {
01221             rc = 0;
01222             const QVariantMap val = r.value();
01223             for( QVariantMap::const_iterator it = val.begin(); it != val.end(); ++it ) {
01224                 QByteArray mapData = it.value().toByteArray();
01225                 if (!mapData.isEmpty()) {
01226                     QDataStream ds(&mapData, QIODevice::ReadOnly);
01227                     QMap<QString,QString> v;
01228                     ds >> v;
01229                     value.insert(it.key(), v);
01230                 }
01231             }
01232         }
01233 #ifdef HAVE_KSECRETSSERVICE
01234     }
01235 #endif
01236 
01237     return rc;
01238 }
01239 
01240 
01241 int Wallet::readPassword(const QString& key, QString& value) {
01242     int rc = -1;
01243 
01244 #ifdef HAVE_KSECRETSSERVICE
01245     if (walletLauncher->m_useKSecretsService) {
01246         rc = d->readEntry<QString>(key, value);
01247     }
01248     else {
01249 #endif
01250         if (d->handle == -1) {
01251             return rc;
01252         }
01253 
01254         QDBusReply<QString> r = walletLauncher->getInterface().readPassword(d->handle, d->folder, key, appid());
01255         if (r.isValid()) {
01256             value = r;
01257             rc = 0;
01258         }
01259 #ifdef HAVE_KSECRETSSERVICE
01260     }
01261 #endif
01262 
01263     return rc;
01264 }
01265 
01266 #ifdef HAVE_KSECRETSSERVICE
01267 struct Wallet::WalletPrivate::InsertIntoPasswordList {
01268     InsertIntoPasswordList( QMap< QString, QString> &value ) : _value( value ) {}
01269     bool operator() ( Wallet::WalletPrivate* d, const QString& label, KSecretsService::SecretItem* ) {
01270         bool result = false;
01271         QString pwd;
01272         if ( d->readEntry<QString>( label, pwd ) == 0 ) {
01273             _value.insert( label, pwd );
01274             result = true;
01275         }
01276         return result;
01277     }
01278     QMap< QString, QString > &_value;
01279 };
01280 #endif
01281 
01282 int Wallet::readPasswordList(const QString& key, QMap<QString, QString>& value) {
01283     int rc = -1;
01284 
01285 #ifdef HAVE_KSECRETSSERVICE
01286     if (walletLauncher->m_useKSecretsService) {
01287         rc = d->forEachItemThatMatches( key, WalletPrivate::InsertIntoPasswordList( value ) );
01288     }
01289     else {
01290 #endif
01291         registerTypes();
01292 
01293         if (d->handle == -1) {
01294             return rc;
01295         }
01296 
01297         QDBusReply<QVariantMap> r = walletLauncher->getInterface().readPasswordList(d->handle, d->folder, key, appid());
01298         if (r.isValid()) {
01299             rc = 0;
01300             const QVariantMap val = r.value();
01301             for( QVariantMap::const_iterator it = val.begin(); it != val.end(); ++it ) {
01302                 value.insert(it.key(), it.value().toString());
01303             }
01304         }
01305 #ifdef HAVE_KSECRETSSERVICE
01306     }
01307 #endif
01308     
01309     return rc;
01310 }
01311 
01312 
01313 int Wallet::writeEntry(const QString& key, const QByteArray& value, EntryType entryType) {
01314     int rc = -1;
01315 
01316 #ifdef HAVE_KSECRETSSERVICE
01317     if (walletLauncher->m_useKSecretsService) {
01318         rc = d->writeEntry( key, value, entryType );
01319     }
01320     else {
01321 #endif
01322         if (d->handle == -1) {
01323             return rc;
01324         }
01325 
01326         QDBusReply<int> r = walletLauncher->getInterface().writeEntry(d->handle, d->folder, key, value, int(entryType), appid());
01327         if (r.isValid()) {
01328             rc = r;
01329         }
01330 #ifdef HAVE_KSECRETSSERVICE
01331     }
01332 #endif
01333 
01334     return rc;
01335 }
01336 
01337 
01338 int Wallet::writeEntry(const QString& key, const QByteArray& value) {
01339     int rc = -1;
01340 
01341 #ifdef HAVE_KSECRETSSERVICE
01342     if (walletLauncher->m_useKSecretsService) {
01343         rc = writeEntry( key, value, Stream );
01344     }
01345     else {
01346 #endif
01347         if (d->handle == -1) {
01348             return rc;
01349         }
01350 
01351         QDBusReply<int> r = walletLauncher->getInterface().writeEntry(d->handle, d->folder, key, value, appid());
01352         if (r.isValid()) {
01353             rc = r;
01354         }
01355 #ifdef HAVE_KSECRETSSERVICE
01356     }
01357 #endif
01358 
01359     return rc;
01360 }
01361 
01362 
01363 int Wallet::writeMap(const QString& key, const QMap<QString,QString>& value) {
01364     int rc = -1;
01365 
01366 #ifdef HAVE_KSECRETSSERVICE
01367     if (walletLauncher->m_useKSecretsService) {
01368         d->writeEntry( key, value, Map );
01369     }
01370     else {
01371 #endif
01372         registerTypes();
01373 
01374         if (d->handle == -1) {
01375             return rc;
01376         }
01377 
01378         QByteArray mapData;
01379         QDataStream ds(&mapData, QIODevice::WriteOnly);
01380         ds << value;
01381         QDBusReply<int> r = walletLauncher->getInterface().writeMap(d->handle, d->folder, key, mapData, appid());
01382         if (r.isValid()) {
01383             rc = r;
01384         }
01385 #ifdef HAVE_KSECRETSSERVICE
01386     }
01387 #endif
01388 
01389     return rc;
01390 }
01391 
01392 
01393 int Wallet::writePassword(const QString& key, const QString& value) {
01394     int rc = -1;
01395 
01396 #ifdef HAVE_KSECRETSSERVICE
01397     if (walletLauncher->m_useKSecretsService) {
01398         rc = d->writeEntry( key, value, Password );
01399     }
01400     else {
01401 #endif
01402         if (d->handle == -1) {
01403             return rc;
01404         }
01405 
01406         QDBusReply<int> r = walletLauncher->getInterface().writePassword(d->handle, d->folder, key, value, appid());
01407         if (r.isValid()) {
01408             rc = r;
01409         }
01410 #ifdef HAVE_KSECRETSSERVICE
01411     }
01412 #endif
01413 
01414     return rc;
01415 }
01416 
01417 
01418 bool Wallet::hasEntry(const QString& key) {
01419 #ifdef HAVE_KSECRETSSERVICE
01420     if (walletLauncher->m_useKSecretsService) {
01421         QExplicitlySharedDataPointer<KSecretsService::SecretItem> item = d->findItem( key );
01422         return item;
01423     }
01424     else {
01425 #endif
01426         if (d->handle == -1) {
01427             return false;
01428         }
01429 
01430         QDBusReply<bool> r = walletLauncher->getInterface().hasEntry(d->handle, d->folder, key, appid());
01431         if (!r.isValid())
01432         {
01433             kDebug(285) << "Invalid DBus reply: " << r.error();
01434             return false;
01435         }
01436         else
01437             return r;
01438 #ifdef HAVE_KSECRETSSERVICE
01439     }
01440 #endif
01441 }
01442 
01443 
01444 int Wallet::removeEntry(const QString& key) {
01445     int rc = -1;
01446 
01447 #ifdef HAVE_KSECRETSSERVICE
01448     if (walletLauncher->m_useKSecretsService) {
01449         QExplicitlySharedDataPointer<KSecretsService::SecretItem> item = d->findItem( key );
01450         if ( item ) {
01451             KSecretsService::SecretItemDeleteJob *deleteJob = item->deleteItem();
01452             if ( !deleteJob->exec() ) {
01453                 kDebug(285) << "Cannot execute SecretItemDeleteJob " << deleteJob->errorString();
01454             }
01455             rc = deleteJob->error();
01456         }
01457     }
01458     else {
01459 #endif
01460         if (d->handle == -1) {
01461             return rc;
01462         }
01463 
01464         QDBusReply<int> r = walletLauncher->getInterface().removeEntry(d->handle, d->folder, key, appid());
01465         if (r.isValid()) {
01466             rc = r;
01467         }
01468 #ifdef HAVE_KSECRETSSERVICE
01469     }
01470 #endif
01471 
01472     return rc;
01473 }
01474 
01475 
01476 Wallet::EntryType Wallet::entryType(const QString& key) {
01477     int rc = 0;
01478 
01479 #ifdef HAVE_KSECRETSSERVICE
01480     if (walletLauncher->m_useKSecretsService) {
01481         QExplicitlySharedDataPointer<KSecretsService::SecretItem> item = d->findItem( key );
01482         if ( item ) {
01483             KSecretsService::ReadItemPropertyJob *readAttrsJob = item->attributes();
01484             if ( readAttrsJob->exec() ) {
01485                 KSecretsService::StringStringMap attrs = readAttrsJob->propertyValue().value<KSecretsService::StringStringMap>();
01486                 if ( attrs.contains( KSS_ATTR_WALLETTYPE ) ) {
01487                     QString entryType = attrs[KSS_ATTR_WALLETTYPE];
01488                     bool ok = false;
01489                     rc = entryType.toInt( &ok );
01490                     if ( !ok ) {
01491                         rc = 0;
01492                         kDebug(285) << KSS_ATTR_WALLETTYPE << " attribute holds non int value " << attrs[KSS_ATTR_WALLETTYPE];
01493                     }
01494                 }
01495             }
01496             else {
01497                 kDebug(285) << "Cannot execute GetSecretItemSecretJob " << readAttrsJob->errorString();
01498             }
01499         }
01500     }
01501     else {
01502 #endif
01503         if (d->handle == -1) {
01504             return Wallet::Unknown;
01505         }
01506 
01507         QDBusReply<int> r = walletLauncher->getInterface().entryType(d->handle, d->folder, key, appid());
01508         if (r.isValid()) {
01509             rc = r;
01510         }
01511 #ifdef HAVE_KSECRETSSERVICE
01512     }
01513 #endif
01514     return static_cast<EntryType>(rc);
01515 }
01516 
01517 
01518 void Wallet::WalletPrivate::walletServiceUnregistered()
01519 {
01520     if (loop) {
01521         loop->quit();
01522     }
01523 
01524     if (handle >= 0) {
01525         q->slotWalletClosed(handle);
01526     }
01527 }
01528 
01529 void Wallet::slotFolderUpdated(const QString& wallet, const QString& folder) {
01530 #ifdef HAVE_KSECRETSSERVICE
01531     if (walletLauncher->m_useKSecretsService) {
01532         // TODO: implement this
01533         Q_ASSERT(0);
01534     }
01535     else {
01536 #endif
01537         if (d->name == wallet) {
01538             emit folderUpdated(folder);
01539         }
01540 #ifdef HAVE_KSECRETSSERVICE
01541     }
01542 #endif
01543 }
01544 
01545 
01546 void Wallet::slotFolderListUpdated(const QString& wallet) {
01547 #ifdef HAVE_KSECRETSSERVICE
01548     if (walletLauncher->m_useKSecretsService) {
01549         // TODO: implement this
01550         Q_ASSERT(0);
01551     }
01552     else {
01553 #endif
01554         if (d->name == wallet) {
01555             emit folderListUpdated();
01556         }
01557 #ifdef HAVE_KSECRETSSERVICE
01558     }
01559 #endif
01560 }
01561 
01562 
01563 void Wallet::slotApplicationDisconnected(const QString& wallet, const QString& application) {
01564 #ifdef HAVE_KSECRETSSERVICE
01565     if (walletLauncher->m_useKSecretsService) {
01566         // TODO: implement this
01567         Q_ASSERT(0);
01568     }
01569     else {
01570 #endif
01571         if (d->handle >= 0
01572             && d->name == wallet
01573             && application == appid()) {
01574             slotWalletClosed(d->handle);
01575         }
01576 #ifdef HAVE_KSECRETSSERVICE
01577     }
01578 #endif
01579 }
01580 
01581 void Wallet::walletAsyncOpened(int tId, int handle) {
01582 #ifdef HAVE_KSECRETSSERVICE
01583     if (walletLauncher->m_useKSecretsService) {
01584         // TODO: implement this
01585         Q_ASSERT(0);
01586     }
01587     else {
01588 #endif
01589         // ignore responses to calls other than ours
01590         if (d->transactionId != tId || d->handle != -1) {
01591             return;
01592         }
01593 
01594         // disconnect the async signal
01595         disconnect(this, SLOT(walletAsyncOpened(int,int)));
01596 
01597         d->handle = handle;
01598         emit walletOpened(handle > 0);
01599 #ifdef HAVE_KSECRETSSERVICE
01600     }
01601 #endif
01602 }
01603 
01604 void Wallet::emitWalletAsyncOpenError() {
01605     emit walletOpened(false);
01606 }
01607 
01608 void Wallet::emitWalletOpened() {
01609   emit walletOpened(true);
01610 }
01611 
01612 bool Wallet::folderDoesNotExist(const QString& wallet, const QString& folder)
01613 {
01614 #ifdef HAVE_KSECRETSSERVICE
01615     if (walletLauncher->m_useKSecretsService) {
01616         kDebug(285) << "WARNING: changing semantics of folderDoesNotExist with KSS: will prompt for the password";
01617         Wallet *w = openWallet( wallet, 0, Synchronous );
01618         if ( w ) {
01619             return !w->hasFolder( folder );
01620         }
01621         else {
01622             return true;
01623         }
01624     }
01625     else {
01626 #endif
01627         QDBusReply<bool> r = walletLauncher->getInterface().folderDoesNotExist(wallet, folder);
01628         if (!r.isValid())
01629         {
01630             kDebug(285) << "Invalid DBus reply: " << r.error();
01631             return false;
01632         }
01633         else
01634             return r;
01635 #ifdef HAVE_KSECRETSSERVICE
01636     }
01637 #endif
01638 }
01639 
01640 
01641 bool Wallet::keyDoesNotExist(const QString& wallet, const QString& folder, const QString& key)
01642 {
01643 #ifdef HAVE_KSECRETSSERVICE
01644     if (walletLauncher->m_useKSecretsService) {
01645         kDebug(285) << "WARNING: changing semantics of keyDoesNotExist with KSS: will prompt for the password";
01646         Wallet *w = openWallet( wallet, 0, Synchronous );
01647         if ( w ) {
01648             return !w->hasEntry(key);
01649         }
01650         return false;
01651     }
01652     else {
01653 #endif
01654         QDBusReply<bool> r = walletLauncher->getInterface().keyDoesNotExist(wallet, folder, key);
01655         if (!r.isValid())
01656         {
01657             kDebug(285) << "Invalid DBus reply: " << r.error();
01658             return false;
01659         }
01660         else
01661             return r;
01662 #ifdef HAVE_KSECRETSSERVICE
01663     }
01664 #endif
01665 }
01666 
01667 void Wallet::virtual_hook(int, void*) {
01668     //BASE::virtual_hook( id, data );
01669 }
01670 
01671 
01672 KWalletDLauncher::KWalletDLauncher()
01673     : m_wallet(0),
01674     m_cgroup(KSharedConfig::openConfig("kwalletrc", KConfig::NoGlobals)->group("Wallet"))
01675 {
01676     m_useKSecretsService = m_cgroup.readEntry("UseKSecretsService", false);
01677 #ifdef HAVE_KSECRETSSERVICE
01678     if (m_useKSecretsService) {
01679         // NOOP
01680     }
01681     else {
01682 #endif
01683         m_wallet = new org::kde::KWallet(QString::fromLatin1(s_kwalletdServiceName), "/modules/kwalletd", QDBusConnection::sessionBus());
01684 #ifdef HAVE_KSECRETSSERVICE
01685     }
01686 #endif
01687 }
01688 
01689 KWalletDLauncher::~KWalletDLauncher()
01690 {
01691     delete m_wallet;
01692 }
01693 
01694 org::kde::KWallet &KWalletDLauncher::getInterface()
01695 {
01696 //    Q_ASSERT(!m_useKSecretsService);
01697     Q_ASSERT(m_wallet != 0);
01698 
01699     // check if kwalletd is already running
01700     if (!QDBusConnection::sessionBus().interface()->isServiceRegistered(QString::fromLatin1(s_kwalletdServiceName)))
01701     {
01702         // not running! check if it is enabled.
01703         bool walletEnabled = m_cgroup.readEntry("Enabled", true);
01704         if (walletEnabled) {
01705             // wallet is enabled! try launching it
01706             QString error;
01707             int ret = KToolInvocation::startServiceByDesktopPath("kwalletd.desktop", QStringList(), &error);
01708             if (ret > 0)
01709             {
01710                 kError(285) << "Couldn't start kwalletd: " << error << endl;
01711             }
01712 
01713             if
01714                 (!QDBusConnection::sessionBus().interface()->isServiceRegistered(QString::fromLatin1(s_kwalletdServiceName))) {
01715                 kDebug(285) << "The kwalletd service is still not registered";
01716             } else {
01717                 kDebug(285) << "The kwalletd service has been registered";
01718             }
01719         } else {
01720             kError(285) << "The kwalletd service has been disabled";
01721         }
01722     }
01723 
01724     return *m_wallet;
01725 }
01726 
01727 } // namespace KWallet
01728 
01729 #include "kwallet.moc"
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Thu May 10 2012 20:53:07 by doxygen 1.8.0 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.8.3 API Reference

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