diff --git a/lang/qt/src/importjob.cpp b/lang/qt/src/importjob.cpp index 3f28606f..4f40d9b1 100644 --- a/lang/qt/src/importjob.cpp +++ b/lang/qt/src/importjob.cpp @@ -53,11 +53,24 @@ struct ImportJobPrivate : public JobPrivate ~ImportJobPrivate() override = default; + QString m_importFilter; Key::Origin m_keyOrigin = Key::OriginUnknown; QString m_keyOriginUrl; }; } +void QGpgME::ImportJob::setImportFilter(const QString &filter) +{ + const auto d = jobPrivate(this); + d->m_importFilter = filter; +} + +QString QGpgME::ImportJob::importFilter() const +{ + const auto d = jobPrivate(this); + return d->m_importFilter; +} + void ImportJob::setKeyOrigin(GpgME::Key::Origin origin, const QString &url) { const auto d = jobPrivate(this); diff --git a/lang/qt/src/importjob.h b/lang/qt/src/importjob.h index 1ded1cde..03b0bcf9 100644 --- a/lang/qt/src/importjob.h +++ b/lang/qt/src/importjob.h @@ -72,6 +72,9 @@ protected: public: ~ImportJob() override; + void setImportFilter(const QString &filter); + QString importFilter() const; + void setKeyOrigin(GpgME::Key::Origin origin, const QString &url = {}); GpgME::Key::Origin keyOrigin() const; QString keyOriginUrl() const; diff --git a/lang/qt/src/qgpgmeimportjob.cpp b/lang/qt/src/qgpgmeimportjob.cpp index ad5c2aee..110250c9 100644 --- a/lang/qt/src/qgpgmeimportjob.cpp +++ b/lang/qt/src/qgpgmeimportjob.cpp @@ -40,11 +40,9 @@ #include "dataprovider.h" -#include "context.h" -#include "data.h" -#include "key.h" - -#include +#include +#include +#include using namespace QGpgME; using namespace GpgME; @@ -72,8 +70,12 @@ static const char *originToString(Key::Origin origin) return (it != std::end(mapping)) ? it->second : nullptr; } -static QGpgMEImportJob::result_type import_qba(Context *ctx, const QByteArray &certData, Key::Origin keyOrigin, const QString &keyOriginUrl) +static QGpgMEImportJob::result_type import_qba(Context *ctx, const QByteArray &certData, const QString &importFilter, + Key::Origin keyOrigin, const QString &keyOriginUrl) { + if (!importFilter.isEmpty()) { + ctx->setFlag("import-filter", importFilter.toStdString().c_str()); + } if (keyOrigin != Key::OriginUnknown) { if (const auto origin = originToString(keyOrigin)) { std::string value{origin}; @@ -96,13 +98,13 @@ static QGpgMEImportJob::result_type import_qba(Context *ctx, const QByteArray &c Error QGpgMEImportJob::start(const QByteArray &certData) { - run(std::bind(&import_qba, std::placeholders::_1, certData, keyOrigin(), keyOriginUrl())); + run(std::bind(&import_qba, std::placeholders::_1, certData, importFilter(), keyOrigin(), keyOriginUrl())); return Error(); } GpgME::ImportResult QGpgME::QGpgMEImportJob::exec(const QByteArray &keyData) { - const result_type r = import_qba(context(), keyData, keyOrigin(), keyOriginUrl()); + const result_type r = import_qba(context(), keyData, importFilter(), keyOrigin(), keyOriginUrl()); resultHook(r); return mResult; } diff --git a/lang/qt/tests/t-import.cpp b/lang/qt/tests/t-import.cpp index a2cb7826..06786bc0 100644 --- a/lang/qt/tests/t-import.cpp +++ b/lang/qt/tests/t-import.cpp @@ -69,6 +69,59 @@ private Q_SLOTS: qputenv("GNUPGHOME", tempGpgHome.path().toLocal8Bit()); } + void testImportWithImportFilter() + { + if (GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "2.1.14") { + QSKIP("gpg does not yet support the --import-filter option"); + } + + // pub ed25519 2021-12-15 [SC] + // E7A0841292ACC9465D3142652FB3A6F51FBF28A2 + // uid [ultimate] importWithImportFilter@example.com + // uid [ultimate] importWithImportFilter@example.net + // sub cv25519 2021-12-15 [E] + static const char keyFpr[] = "E7A0841292ACC9465D3142652FB3A6F51FBF28A2"; + static const char keyData[] = + "-----BEGIN PGP PUBLIC KEY BLOCK-----\n" + "\n" + "mDMEYbm2PhYJKwYBBAHaRw8BAQdACzxBWtNNsmJ6rzpZkjh1yBe+Ajsk9NR8umEu\n" + "Da3HLgG0ImltcG9ydFdpdGhJbXBvcnRGaWx0ZXJAZXhhbXBsZS5uZXSIlAQTFgoA\n" + "PBYhBOeghBKSrMlGXTFCZS+zpvUfvyiiBQJhubY+AhsDBQsJCAcCAyICAQYVCgkI\n" + "CwIEFgIDAQIeBwIXgAAKCRAvs6b1H78oosRgAQCc/ke6q076nvzIE2UzT83JK/B6\n" + "lxSV7Fb8bKltOMpvsAD+Phap3EzA8jdMyKoO0FM926bw5lX7QROfeZ/JBYqyPwC0\n" + "ImltcG9ydFdpdGhJbXBvcnRGaWx0ZXJAZXhhbXBsZS5jb22IlAQTFgoAPBYhBOeg\n" + "hBKSrMlGXTFCZS+zpvUfvyiiBQJhubZlAhsDBQsJCAcCAyICAQYVCgkICwIEFgID\n" + "AQIeBwIXgAAKCRAvs6b1H78oohPWAQC/u9UXzkxRkrB2huaTZCsyimWEGZIMmxWd\n" + "tE+vN9/IvQD/Yzia+xRS6yca3Yz6iW8xS844ZqRxvkUEHjtJXSOzagm4OARhubY+\n" + "EgorBgEEAZdVAQUBAQdANQFjmDctY3N0/ELPZtj9tapwFs4vrmTVpx/SCfZmihkD\n" + "AQgHiHgEGBYKACAWIQTnoIQSkqzJRl0xQmUvs6b1H78oogUCYbm2PgIbDAAKCRAv\n" + "s6b1H78oovGyAP41ySzvvDpV7XDJBOAFxvWLmywa5IcO7Lrg7y1efoWj0AD+Kk/B\n" + "s7jGLdoG51h670h50MMoYCANB6MwAdSP+qZUlQg=\n" + "=/3O0\n" + "-----END PGP PUBLIC KEY BLOCK-----\n"; + + auto *job = openpgp()->importJob(); + job->setImportFilter(QLatin1String{"keep-uid=mbox = importWithImportFilter@example.net"}); + connect(job, &ImportJob::result, this, + [this](ImportResult result, QString, Error) + { + QVERIFY(!result.error()); + QVERIFY(!result.imports().empty()); + QVERIFY(result.numImported()); + Q_EMIT asyncDone(); + }); + job->start(QByteArray{keyData}); + QSignalSpy spy (this, SIGNAL(asyncDone())); + QVERIFY(spy.wait()); + + auto ctx = Context::createForProtocol(GpgME::OpenPGP); + GpgME::Error err; + const auto key = ctx->key(keyFpr, err, false); + QVERIFY(!key.isNull()); + QCOMPARE(key.numUserIDs(), 1); + QCOMPARE(key.userID(0).id(), "importWithImportFilter@example.net"); + } + void testImportWithKeyOrigin() { if (GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "2.1.22") {