diff options
Diffstat (limited to 'lang/qt')
| -rw-r--r-- | lang/qt/src/qgpgmelistallkeysjob.cpp | 61 | ||||
| -rw-r--r-- | lang/qt/tests/t-keylist.cpp | 64 | 
2 files changed, 116 insertions, 9 deletions
| 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 <gpg-error.h>  #include <algorithm> @@ -61,7 +64,9 @@ QGpgMEListAllKeysJob::QGpgMEListAllKeysJob(Context *context)  QGpgMEListAllKeysJob::~QGpgMEListAllKeysJob() {} -static KeyListResult do_list_keys(Context *ctx, std::vector<Key> &keys, bool secretOnly) +namespace { + +static KeyListResult do_list_keys_legacy(Context *ctx, std::vector<Key> &keys, bool secretOnly)  {      const char **pat = nullptr; @@ -81,9 +86,6 @@ static KeyListResult do_list_keys(Context *ctx, std::vector<Key> &keys, bool sec      return result;  } -namespace -{ -  template <typename ForwardIterator, typename BinaryPredicate>  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<Key> &merged, std::vector<Key> &pub, std::vector<Key> &sec)  {      merged.reserve(pub.size() + sec.size()); @@ -118,15 +118,15 @@ static void merge_keys(std::vector<Key> &merged, std::vector<Key> &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<Key> 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<std::less>()); -    r.mergeWith(do_list_keys(ctx, sec, true)); +    r.mergeWith(do_list_keys_legacy(ctx, sec, true));      std::sort(sec.begin(), sec.end(), ByFingerprint<std::less>());      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<Key> &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<Key> keys; +    KeyListResult r = do_list_keys(ctx, keys); +    std::sort(keys.begin(), keys.end(), ByFingerprint<std::less>()); + +    std::vector<Key> 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)); diff --git a/lang/qt/tests/t-keylist.cpp b/lang/qt/tests/t-keylist.cpp index 21349c1c..5875dfb4 100644 --- a/lang/qt/tests/t-keylist.cpp +++ b/lang/qt/tests/t-keylist.cpp @@ -39,10 +39,12 @@  #include <QSignalSpy>  #include <QMap>  #include "keylistjob.h" +#include "listallkeysjob.h"  #include "qgpgmebackend.h"  #include "keylistresult.h"  #include "context.h" +#include "engineinfo.h"  #include <memory> @@ -138,6 +140,68 @@ private Q_SLOTS:          QSignalSpy spy (this, SIGNAL(asyncDone()));          QVERIFY(spy.wait(QSIGNALSPY_TIMEOUT));      } + +    void testListAllKeysSync() +    { +        const auto accumulateFingerprints = [](std::vector<std::string> &v, const Key &key) { v.push_back(std::string(key.primaryFingerprint())); return v; }; + +        ListAllKeysJob *job = openpgp()->listAllKeysJob(/* includeSigs= */false, /* validate= */false); +        std::vector<GpgME::Key> pubKeys, secKeys; +        GpgME::KeyListResult result = job->exec(pubKeys, secKeys, /* mergeKeys= */false); // mergeKeys is unused for GnuPG >= 2.1 +        delete job; +        QVERIFY(!result.error()); + +        QCOMPARE(secKeys.size(), 2u); +        std::vector<std::string> secKeyFingerprints = std::accumulate(secKeys.begin(), secKeys.end(), std::vector<std::string>(), accumulateFingerprints); +        QCOMPARE(secKeyFingerprints, std::vector<std::string>({ +                "23FD347A419429BACCD5E72D6BC4778054ACD246", +                "A0FF4590BB6122EDEF6E3C542D727CC768697734" +        })); +        QVERIFY(secKeys[0].hasSecret()); +        if (!(GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "2.1.0")) { +            QVERIFY(secKeys[0].subkeys()[0].keyGrip()); +        } + +        QCOMPARE(pubKeys.size(), 26u); +        std::vector<std::string> pubKeyFingerprints = std::accumulate(pubKeys.begin(), pubKeys.end(), std::vector<std::string>(), accumulateFingerprints); +        QCOMPARE(pubKeyFingerprints, std::vector<std::string>({ +                "045B2334ADD69FC221076841A5E67F7FA3AE3EA1", +                "04C1DF62EFA0EBB00519B06A8979A6C5567FB34A", +                "0DBCAD3F08843B9557C6C4D4A94C0F75653244D6", +                "1DDD28CEF714F5B03B8C246937CAB51FB79103F8", +                "23FD347A419429BACCD5E72D6BC4778054ACD246", +                "2686AA191A278013992C72EBBE794852BE5CF886", +                "3531152DE293E26A07F504BC318C1FAEFAEF6D1B", +                "38FBE1E4BF6A5E1242C8F6A13BDBEDB1777FBED3", +                "3FD11083779196C2ECDD9594AD1B0FAD43C2D0C7", +                "43929E89F8F79381678CAE515F6356BA6D9732AC", +                "56D33268F7FE693FBB594762D4BF57F37372E243", +                "5AB9D6D7BAA1C95B3BAA3D9425B00FD430CEC684", +                "61EE841A2A27EB983B3B3C26413F4AF31AFDAB6C", +                "6560C59C43D031C54D7C588EEBA9F240EB9DC9E6", +                "6FAA9C201E5E26DCBAEC39FD5D15E01D3FF13206", +                "9E91CBB11E4D4135583EF90513DB965534C6E3F1", +                "A0FF4590BB6122EDEF6E3C542D727CC768697734", +                "A7969DA1C3297AA96D49843F1C67EC133C661C84", +                "C9C07DCC6621B9FB8D071B1D168410A48FC282E6", +                "CD538D6CC9FB3D745ECDA5201FE8FC6F04259677", +                "D695676BDCEDCC2CDD6152BCFE180B1DA9E3B0B2", +                "E8143C489C8D41124DC40D0B47AF4B6961F04784", +                "E8D6C90B683B0982BD557A99DEF0F7B8EC67DBDE", +                "ECAC774F4EEEB0620767044A58CB9A4C85A81F38", +                "ED9B316F78644A58D042655A9EEF34CD4B11B25F", +                "F8F1EDC73995AB739AD54B380C820C71D2699313" +        })); +        if (!(GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "2.1.0")) { +            // with GnuPG >= 2.1 the job always lists keys with --with-keygrip and --with-secret, +            // i.e. the key grips and information about secret keys are always available +            QVERIFY(!pubKeys[0].hasSecret()); +            QVERIFY(pubKeys[0].subkeys()[0].keyGrip()); + +            QVERIFY(pubKeys[4].hasSecret()); +            QVERIFY(pubKeys[4].subkeys()[0].keyGrip()); +        } +    }  };  QTEST_MAIN(KeyListTest) | 
