diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,7 @@ include(KDECMakeSettings) include(ECMAddQch) +include(ECMGenerateExportHeader) include(ECMSetupVersion) include(ECMQtDeclareLoggingCategory) diff --git a/src/api/KWallet/CMakeLists.txt b/src/api/KWallet/CMakeLists.txt --- a/src/api/KWallet/CMakeLists.txt +++ b/src/api/KWallet/CMakeLists.txt @@ -42,7 +42,15 @@ ) add_library(KF5Wallet ${kwallet_SRCS}) -generate_export_header(KF5Wallet BASE_NAME KWallet) +ecm_generate_export_header(KF5Wallet + BASE_NAME KWallet + GROUP_BASE_NAME KF + VERSION ${KF5_VERSION} + DEPRECATED_BASE_VERSION 0 + DEPRECATION_VERSIONS 5.70 + EXCLUDE_DEPRECATED_BEFORE_AND_AT ${EXCLUDE_DEPRECATED_BEFORE_AND_AT} +) + add_library(KF5::Wallet ALIAS KF5Wallet) target_include_directories(KF5Wallet INTERFACE "$") diff --git a/src/api/KWallet/kwallet.h b/src/api/KWallet/kwallet.h --- a/src/api/KWallet/kwallet.h +++ b/src/api/KWallet/kwallet.h @@ -327,6 +327,7 @@ */ virtual int readPassword(const QString &key, QString &value); +#if KWALLET_ENABLE_DEPRECATED_SINCE(5, 70) /** * Read the entries matching @p key from the current folder. * The entry format is unknown except that it is either a @@ -337,6 +338,8 @@ * @param value A buffer to fill with the value. The key in * the map is the entry key. * @return Returns 0 on success, non-zero on error. + * + * @deprecated Since 5.70, use entriesList() */ int readEntryList(const QString &key, QMap &value); @@ -349,6 +352,8 @@ * @return Returns 0 on success, non-zero on error. Will * return an error if the key was not originally * written as a map. + * + * @deprecated Since 5.70, use mapList() */ int readMapList(const QString &key, QMap > &value); @@ -361,8 +366,49 @@ * @return Returns 0 on success, non-zero on error. Will * return an error if the key was not originally * written as a password. + * + * @deprecated Since 5.70, use passwordList() */ int readPasswordList(const QString &key, QMap &value); +#endif + + /** + * Get a list of all the entries in the current folder. The entry + * format is unknown except that it is either a QByteArray or a + * QDataStream, which effectively means that it could be anything. + * + * @param value A buffer to fill with the value. The key in the map + * is the entry key. + * @return Returns 0 on success, non-zero on error. + * + * @since 5.70 + */ + int entriesList(QMap &value); + + /** + * Get a list of all the maps in the current folder. + * @param value A buffer to fill with the value. The key in the + * map is the entry key. + * @return Returns 0 on success, non-zero on error. Will return an + * error if any of the keys was not originally written as + * a map. + * + * @since 5.70 + */ + int mapList(QMap > &value); + + /** + * Get a list of all the passwords in the current folder, which can + * be used to populate a list view in a password manager. + * @param value A buffer to fill with the value. The key in the + * map is the entry key. + * @return Returns 0 on success, non-zero on error. Will return an + * error if any of the keys was not originally written as a + * password. + * + * @since 5.70 + */ + int passwordList(QMap &value); /** * Write @p key = @p value as a binary entry to the current diff --git a/src/api/KWallet/kwallet.cpp b/src/api/KWallet/kwallet.cpp --- a/src/api/KWallet/kwallet.cpp +++ b/src/api/KWallet/kwallet.cpp @@ -169,6 +169,7 @@ template int readEntry(const QString &key, T &value) const; bool readSecret(const QString &key, KSecretsService::Secret &value) const; +#if KWALLET_BUILD_DEPRECATED_SINCE(5, 70) template int forEachItemThatMatches(const QString &key, V verb) { @@ -203,6 +204,32 @@ } return rc; } +#endif + + template int checkItems(V verb) + { + int rc = -1; + KSecretsService::StringStringMap attrs; + attrs[KSS_ATTR_ENTRYFOLDER] = folder; + KSecretsService::SearchCollectionItemsJob *searchItemsJob = secretsCollection->searchItems(attrs); + if (searchItemsJob->exec()) { + const auto list = searchItemsJob->items(); + for (KSecretsService::SearchCollectionItemsJob::Item item : list) { + KSecretsService::ReadItemPropertyJob *readLabelJob = item->label(); + if (readLabelJob->exec()) { + const QString label = readLabelJob->propertyValue().toString(); + if (verb(this, label, item.data())) { + rc = 0; // one successful iteration already produced results, so success return + } + } else { + qCDebug(KWALLET_API_LOG) << "Cannot execute ReadItemPropertyJob " << readLabelJob->errorString(); + } + } + } else { + qCDebug(KWALLET_API_LOG) << "Cannot execute KSecretsService::SearchCollectionItemsJob " << searchItemsJob->errorString(); + } + return rc; + } void createDefaultFolders(); @@ -1046,6 +1073,7 @@ }; #endif +#if KWALLET_BUILD_DEPRECATED_SINCE(5, 70) int Wallet::readEntryList(const QString &key, QMap &value) { @@ -1077,6 +1105,40 @@ return rc; } +#endif + +int Wallet::entriesList(QMap &value) +{ + + int rc = -1; + +#if HAVE_KSECRETSSERVICE + if (walletLauncher()->m_useKSecretsService) { + rc = d->checkItems(WalletPrivate::InsertIntoEntryList(value)); + } else { +#endif + registerTypes(); + + if (d->handle == -1) { + return rc; + } + + QDBusReply reply = walletLauncher()->getInterface().entriesList(d->handle, d->folder, appid()); + if (reply.isValid()) { + rc = 0; + // convert to + const QVariantMap val = reply.value(); + for (QVariantMap::const_iterator it = val.begin(); it != val.end(); ++it) { + value.insert(it.key(), it.value().toByteArray()); + } + } +#if HAVE_KSECRETSSERVICE + } +#endif + + return rc; +} + int Wallet::renameEntry(const QString &oldName, const QString &newName) { @@ -1164,6 +1226,7 @@ }; #endif +#if KWALLET_BUILD_DEPRECATED_SINCE(5, 70) int Wallet::readMapList(const QString &key, QMap > &value) { int rc = -1; @@ -1200,6 +1263,43 @@ return rc; } +#endif + +int Wallet::mapList(QMap > &value) +{ + int rc = -1; + +#if HAVE_KSECRETSSERVICE + if (walletLauncher()->m_useKSecretsService) { + rc = d->checkItems(WalletPrivate::InsertIntoMapList(value)); + } else { +#endif + registerTypes(); + + if (d->handle == -1) { + return rc; + } + + QDBusReply reply = walletLauncher()->getInterface().mapList(d->handle, d->folder, appid()); + if (reply.isValid()) { + rc = 0; + const QVariantMap val = reply.value(); + for (QVariantMap::const_iterator it = val.begin(); it != val.end(); ++it) { + QByteArray mapData = it.value().toByteArray(); + if (!mapData.isEmpty()) { + QDataStream ds(&mapData, QIODevice::ReadOnly); + QMap v; + ds >> v; + value.insert(it.key(), v); + } + } + } +#if HAVE_KSECRETSSERVICE + } +#endif + + return rc; +} int Wallet::readPassword(const QString &key, QString &value) { @@ -1243,6 +1343,7 @@ }; #endif +#if KWALLET_BUILD_DEPRECATED_SINCE(5, 70) int Wallet::readPasswordList(const QString &key, QMap &value) { int rc = -1; @@ -1272,6 +1373,37 @@ return rc; } +#endif + +int Wallet::passwordList(QMap &value) +{ + int rc = -1; + +#if HAVE_KSECRETSSERVICE + if (walletLauncher()->m_useKSecretsService) { + rc = d->checkItems(WalletPrivate::InsertIntoPasswordList(value)); + } else { +#endif + registerTypes(); + + if (d->handle == -1) { + return rc; + } + + QDBusReply reply = walletLauncher()->getInterface().passwordList(d->handle, d->folder, appid()); + if (reply.isValid()) { + rc = 0; + const QVariantMap val = reply.value(); + for (QVariantMap::const_iterator it = val.begin(); it != val.end(); ++it) { + value.insert(it.key(), it.value().toString()); + } + } +#if HAVE_KSECRETSSERVICE + } +#endif + + return rc; +} int Wallet::writeEntry(const QString &key, const QByteArray &value, EntryType entryType) { diff --git a/src/api/KWallet/org.kde.KWallet.xml b/src/api/KWallet/org.kde.KWallet.xml --- a/src/api/KWallet/org.kde.KWallet.xml +++ b/src/api/KWallet/org.kde.KWallet.xml @@ -162,22 +162,43 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/runtime/kwalletd/backend/kwalletbackend.h b/src/runtime/kwalletd/backend/kwalletbackend.h --- a/src/runtime/kwalletd/backend/kwalletbackend.h +++ b/src/runtime/kwalletd/backend/kwalletbackend.h @@ -129,9 +129,17 @@ // Look up an entry. Returns null if it doesn't exist. Entry *readEntry(const QString &key); +#if KWALLET_ENABLE_DEPRECATED_SINCE(5, 70) // Look up a list of entries. Supports wildcards. - // You delete the list + // You delete the list. + // Deprecated since 5.70, use entriesList() QList readEntryList(const QString &key); +#endif + + // Get a list of all the entries in the current folder. + // You delete the list. + // @since 5.70 + QList entriesList(); // Store an entry. void writeEntry(Entry *e); diff --git a/src/runtime/kwalletd/backend/kwalletbackend.cc b/src/runtime/kwalletd/backend/kwalletbackend.cc --- a/src/runtime/kwalletd/backend/kwalletbackend.cc +++ b/src/runtime/kwalletd/backend/kwalletbackend.cc @@ -523,6 +523,7 @@ return rc; } +#if KWALLET_BUILD_DEPRECATED_SINCE(5, 70) QList Backend::readEntryList(const QString &key) { QList rc; @@ -544,6 +545,21 @@ } return rc; } +#endif + +QList Backend::entriesList() +{ + QList rc; + + if (!_open) { + return rc; + } + const EntryMap &map = _entries[_folder]; + rc.append(map.values()); + + return rc; +} + bool Backend::createFolder(const QString &f) { diff --git a/src/runtime/kwalletd/kwalletd.h b/src/runtime/kwalletd/kwalletd.h --- a/src/runtime/kwalletd/kwalletd.h +++ b/src/runtime/kwalletd/kwalletd.h @@ -115,9 +115,19 @@ QByteArray readEntry(int handle, const QString &folder, const QString &key, const QString &appid); QByteArray readMap(int handle, const QString &folder, const QString &key, const QString &appid); QString readPassword(int handle, const QString &folder, const QString &key, const QString &appid); + +#if KWALLET_ENABLE_DEPRECATED_SINCE(5, 70) + // use entriesList() QVariantMap readEntryList(int handle, const QString &folder, const QString &key, const QString &appid); + // use mapList() QVariantMap readMapList(int handle, const QString &folder, const QString &key, const QString &appid); + // use passwordList() QVariantMap readPasswordList(int handle, const QString &folder, const QString &key, const QString &appid); +#endif + + QVariantMap entriesList(int handle, const QString &folder, const QString &appid); + QVariantMap mapList(int handle, const QString &folder, const QString &appid); + QVariantMap passwordList(int handle, const QString &folder, const QString &appid); // Rename an entry. rc=0 on success. int renameEntry(int handle, const QString &folder, const QString &oldName, const QString &newName, const QString &appid); diff --git a/src/runtime/kwalletd/kwalletd.cpp b/src/runtime/kwalletd/kwalletd.cpp --- a/src/runtime/kwalletd/kwalletd.cpp +++ b/src/runtime/kwalletd/kwalletd.cpp @@ -1297,6 +1297,7 @@ return QByteArray(); } +#if KWALLET_BUILD_DEPRECATED_SINCE(5, 70) QVariantMap KWalletD::readMapList(int handle, const QString& folder, const QString& key, const QString& appid) { @@ -1316,6 +1317,25 @@ return QVariantMap(); } +#endif + +QVariantMap KWalletD::mapList(int handle, const QString &folder, const QString &appid) +{ + QVariantMap rc; + + KWallet::Backend *backend = getWallet(appid, handle); + if (backend) { + backend->setFolder(folder); + const QList lst = backend->entriesList(); + for (KWallet::Entry *entry : lst) { + if (entry->type() == KWallet::Wallet::Map) { + rc.insert(entry->key(), entry->map()); + } + } + } + + return rc; +} QByteArray KWalletD::readEntry(int handle, const QString& folder, const QString& key, const QString& appid) @@ -1333,6 +1353,7 @@ return QByteArray(); } +#if KWALLET_BUILD_DEPRECATED_SINCE(5, 70) QVariantMap KWalletD::readEntryList(int handle, const QString& folder, const QString& key, const QString& appid) { @@ -1350,6 +1371,24 @@ return QVariantMap(); } +#endif + +QVariantMap KWalletD::entriesList(int handle, const QString &folder, const QString &appid) +{ + + QVariantMap rc; + + KWallet::Backend *backend = getWallet(appid, handle); + if (backend) { + backend->setFolder(folder); + const QList lst = backend->entriesList(); + for (KWallet::Entry *entry : lst) { + rc.insert(entry->key(), entry->value()); + } + } + + return rc; +} QStringList KWalletD::entryList( int handle, const QString& folder, const QString& appid) @@ -1380,6 +1419,7 @@ return QString(); } +#if KWALLET_BUILD_DEPRECATED_SINCE(5, 70) QVariantMap KWalletD::readPasswordList(int handle, const QString& folder, const QString& key, const QString& appid) { @@ -1399,6 +1439,25 @@ return QVariantMap(); } +#endif + +QVariantMap KWalletD::passwordList(int handle, const QString &folder, const QString &appid) +{ + QVariantMap rc; + + KWallet::Backend *backend = getWallet(appid, handle); + if (backend) { + backend->setFolder(folder); + const QList lst = backend->entriesList(); + for (KWallet::Entry *entry : lst) { + if (entry->type() == KWallet::Wallet::Password) { + rc.insert(entry->key(), entry->password()); + } + } + } + + return rc; +} int KWalletD::writeMap(int handle, const QString& folder, const QString& key, const QByteArray& value, const QString& appid)