From 13bcc6680ac2030d45e4f36a64864bcd6a1d42a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ingo=20Kl=C3=B6cker?= Date: Mon, 7 Sep 2020 12:02:29 +0200 Subject: qt: List keys once with --with-secret instead of twice * lang/qt/src/qgpgmelistallkeysjob.cpp (do_list_keys): Rename to do_list_keys_legacy and put into unnamed namespace. (merge_keys): Put into unnamed namespace. (list_keys): Rename to list_keys_legacy and put into unnamed namespace. (do_list_keys, list_keys): New. * lang/qt/tests/t-keylist.cpp (testListAllKeysSync): New. -- With gpg >= 2.1, list keys once with --with-secret instead of listing public keys and secret keys and then merging (part of) the information about the keys. GnuPG-bug-id: 4794 --- lang/qt/src/qgpgmelistallkeysjob.cpp | 61 ++++++++++++++++++++++++++++++------ 1 file changed, 52 insertions(+), 9 deletions(-) (limited to 'lang/qt/src') diff --git a/lang/qt/src/qgpgmelistallkeysjob.cpp b/lang/qt/src/qgpgmelistallkeysjob.cpp index 82483f25..6f169ac9 100644 --- a/lang/qt/src/qgpgmelistallkeysjob.cpp +++ b/lang/qt/src/qgpgmelistallkeysjob.cpp @@ -40,7 +40,10 @@ #include "key.h" #include "context.h" +#include "engineinfo.h" +#include "global.h" #include "keylistresult.h" + #include #include @@ -61,7 +64,9 @@ QGpgMEListAllKeysJob::QGpgMEListAllKeysJob(Context *context) QGpgMEListAllKeysJob::~QGpgMEListAllKeysJob() {} -static KeyListResult do_list_keys(Context *ctx, std::vector &keys, bool secretOnly) +namespace { + +static KeyListResult do_list_keys_legacy(Context *ctx, std::vector &keys, bool secretOnly) { const char **pat = nullptr; @@ -81,9 +86,6 @@ static KeyListResult do_list_keys(Context *ctx, std::vector &keys, bool sec return result; } -namespace -{ - template ForwardIterator unique_by_merge(ForwardIterator first, ForwardIterator last, BinaryPredicate pred) { @@ -103,8 +105,6 @@ ForwardIterator unique_by_merge(ForwardIterator first, ForwardIterator last, Bin return ++dest; } -} - static void merge_keys(std::vector &merged, std::vector &pub, std::vector &sec) { merged.reserve(pub.size() + sec.size()); @@ -118,15 +118,15 @@ static void merge_keys(std::vector &merged, std::vector &pub, std::vec merged.end()); } -static QGpgMEListAllKeysJob::result_type list_keys(Context *ctx, bool mergeKeys) +static QGpgMEListAllKeysJob::result_type list_keys_legacy(Context *ctx, bool mergeKeys) { std::vector pub, sec, merged; KeyListResult r; - r.mergeWith(do_list_keys(ctx, pub, false)); + r.mergeWith(do_list_keys_legacy(ctx, pub, false)); std::sort(pub.begin(), pub.end(), ByFingerprint()); - r.mergeWith(do_list_keys(ctx, sec, true)); + r.mergeWith(do_list_keys_legacy(ctx, sec, true)); std::sort(sec.begin(), sec.end(), ByFingerprint()); if (mergeKeys) { @@ -137,6 +137,49 @@ static QGpgMEListAllKeysJob::result_type list_keys(Context *ctx, bool mergeKeys) return std::make_tuple(r, merged, sec, QString(), Error()); } +static KeyListResult do_list_keys(Context *ctx, std::vector &keys) +{ + const unsigned int keyListMode = ctx->keyListMode(); + ctx->addKeyListMode(KeyListMode::WithSecret); + + const char **pat = nullptr; + if (const Error err = ctx->startKeyListing(pat)) { + ctx->setKeyListMode(keyListMode); + return KeyListResult(nullptr, err); + } + + Error err; + do { + keys.push_back(ctx->nextKey(err)); + } while (!err); + + keys.pop_back(); + + const KeyListResult result = ctx->endKeyListing(); + ctx->setKeyListMode(keyListMode); + + ctx->cancelPendingOperation(); + return result; +} + +static QGpgMEListAllKeysJob::result_type list_keys(Context *ctx, bool mergeKeys) +{ + if (GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "2.1.0") { + return list_keys_legacy(ctx, mergeKeys); + } + + std::vector keys; + KeyListResult r = do_list_keys(ctx, keys); + std::sort(keys.begin(), keys.end(), ByFingerprint()); + + std::vector sec; + std::copy_if(keys.begin(), keys.end(), std::back_inserter(sec), [](const Key &key) { return key.hasSecret(); }); + + return std::make_tuple(r, keys, sec, QString(), Error()); +} + +} + Error QGpgMEListAllKeysJob::start(bool mergeKeys) { run(std::bind(&list_keys, std::placeholders::_1, mergeKeys)); -- cgit v1.2.3