aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Klöcker <[email protected]>2023-08-23 10:00:26 +0000
committerIngo Klöcker <[email protected]>2023-08-23 10:00:26 +0000
commit3f297387bf401475385c458e4d1d95b3eefaf3d8 (patch)
tree84c417987274d7a78a3579e6bf8e46b6bdbb0c46
parentqt,tests: Fix build in source directory, part 2 (diff)
downloadgpgme-3f297387bf401475385c458e4d1d95b3eefaf3d8.tar.gz
gpgme-3f297387bf401475385c458e4d1d95b3eefaf3d8.zip
qt: Allow specifying user IDs to use when refreshing keys via WKD
* lang/qt/src/wkdrefreshjob.h, lang/qt/src/wkdrefreshjob.cpp (WKDRefreshJob::start): New overload. * lang/qt/src/wkdrefreshjob_p.h (WKDRefreshJobPrivate): Add field m_userIds. * lang/qt/src/qgpgmewkdrefreshjob.cpp (toEmailAddresses): New. (locate_external_keys): Change return type and arguments. (refresh_keys): Remove. (QGpgMEWKDRefreshJobPrivate::startIt): Get emails from keys or user IDs. Remove duplicates. Call locate_external_keys instead of refresh_keys. * lang/qt/tests/run-wkdrefreshjob.cpp (CommandLineOptions, parseCommandLine): New. (main): Support new option --all-userids. -- The new start() overload allows to specify the user IDs to use for the WKD lookup explicitly. This allows updating user IDs via WKD which were originally not retrieved via WKD. GnuPG-bug-id: 6672
-rw-r--r--lang/qt/src/qgpgmewkdrefreshjob.cpp40
-rw-r--r--lang/qt/src/wkdrefreshjob.cpp7
-rw-r--r--lang/qt/src/wkdrefreshjob.h15
-rw-r--r--lang/qt/src/wkdrefreshjob_p.h1
-rw-r--r--lang/qt/tests/run-wkdrefreshjob.cpp52
5 files changed, 88 insertions, 27 deletions
diff --git a/lang/qt/src/qgpgmewkdrefreshjob.cpp b/lang/qt/src/qgpgmewkdrefreshjob.cpp
index 8bad1ef1..f590ed4b 100644
--- a/lang/qt/src/qgpgmewkdrefreshjob.cpp
+++ b/lang/qt/src/qgpgmewkdrefreshjob.cpp
@@ -88,6 +88,21 @@ static QStringList toEmailAddressesOriginatingFromWKD(const std::vector<GpgME::K
return emails;
}
+static QStringList toEmailAddresses(const std::vector<GpgME::UserID> &userIds)
+{
+ const QStringList emails = std::accumulate(
+ std::begin(userIds),
+ std::end(userIds),
+ QStringList{},
+ [](QStringList &emails, const UserID &userId) {
+ if (!userId.isRevoked() && !userId.addrSpec().empty()) {
+ emails.push_back(QString::fromStdString(userId.addrSpec()));
+ }
+ return emails;
+ });
+ return emails;
+}
+
}
QGpgMEWKDRefreshJob::QGpgMEWKDRefreshJob(Context *context)
@@ -99,12 +114,11 @@ QGpgMEWKDRefreshJob::QGpgMEWKDRefreshJob(Context *context)
QGpgMEWKDRefreshJob::~QGpgMEWKDRefreshJob() = default;
-static ImportResult locate_external_keys(Context *ctx, const std::vector<Key> &keys)
+static QGpgMEWKDRefreshJob::result_type locate_external_keys(Context *ctx, const QStringList &emails)
{
- const auto emails = toEmailAddressesOriginatingFromWKD(keys);
qCDebug(QGPGME_LOG) << __func__ << "locating external keys for" << emails;
if (emails.empty()) {
- return ImportResult{};
+ return std::make_tuple(ImportResult{}, QString{}, Error{});
}
Context::KeyListModeSaver saver{ctx};
@@ -121,24 +135,22 @@ static ImportResult locate_external_keys(Context *ctx, const std::vector<Key> &k
qCDebug(QGPGME_LOG) << __func__ << "result:" << toLogString(result).c_str();
job.release();
- return result;
-}
-
-static QGpgMEWKDRefreshJob::result_type refresh_keys(Context *ctx, const std::vector<Key> &keys)
-{
- const auto result = locate_external_keys(ctx, keys);
-
return std::make_tuple(result, QString{}, Error{});
}
GpgME::Error QGpgMEWKDRefreshJobPrivate::startIt()
{
- if (m_keys.empty()) {
- return Error::fromCode(GPG_ERR_INV_VALUE);
+ QStringList emails;
+ if (!m_keys.empty()) {
+ emails = toEmailAddressesOriginatingFromWKD(m_keys);
+ } else {
+ emails = toEmailAddresses(m_userIds);
}
+ std::sort(emails.begin(), emails.end());
+ emails.erase(std::unique(emails.begin(), emails.end()), emails.end());
- q->run([=](Context *ctx) {
- return refresh_keys(ctx, m_keys);
+ q->run([emails](Context *ctx) {
+ return locate_external_keys(ctx, emails);
});
return {};
diff --git a/lang/qt/src/wkdrefreshjob.cpp b/lang/qt/src/wkdrefreshjob.cpp
index 37b990c8..f79df2c5 100644
--- a/lang/qt/src/wkdrefreshjob.cpp
+++ b/lang/qt/src/wkdrefreshjob.cpp
@@ -54,4 +54,11 @@ GpgME::Error WKDRefreshJob::start(const std::vector<GpgME::Key> &keys)
return d->startIt();
}
+GpgME::Error WKDRefreshJob::start(const std::vector<GpgME::UserID> &userIDs)
+{
+ auto d = jobPrivate<WKDRefreshJobPrivate>(this);
+ d->m_userIds = userIDs;
+ return d->startIt();
+}
+
#include "wkdrefreshjob.moc"
diff --git a/lang/qt/src/wkdrefreshjob.h b/lang/qt/src/wkdrefreshjob.h
index c3aec65f..cbaaf6b0 100644
--- a/lang/qt/src/wkdrefreshjob.h
+++ b/lang/qt/src/wkdrefreshjob.h
@@ -43,14 +43,14 @@ namespace GpgME
{
class Error;
class Key;
+class UserID;
}
namespace QGpgME
{
/**
- * This job refreshes OpenPGP keys via WKD. Only user IDs that have WKD set as
- * origin are used for the WKD lookup. Revoked user IDs are ignored.
+ * This job refreshes OpenPGP keys via WKD.
*/
class QGPGME_EXPORT WKDRefreshJob : public AbstractImportJob
{
@@ -61,9 +61,18 @@ public:
~WKDRefreshJob() override;
/**
- * Starts a refresh of the \a keys.
+ * Starts a refresh of the \a keys. Only user IDs that have WKD set as
+ * origin are used for the WKD lookup. Revoked user IDs are ignored.
+ *
+ * Use the other start overload to use all user IDs for the WKD lookup.
*/
GpgME::Error start(const std::vector<GpgME::Key> &keys);
+
+ /**
+ * Starts a refresh of the keys belonging to the user IDs \a userIDs.
+ * All user IDs are used for the WKD lookup. Revoked user IDs are ignored.
+ */
+ GpgME::Error start(const std::vector<GpgME::UserID> &userIDs);
};
}
diff --git a/lang/qt/src/wkdrefreshjob_p.h b/lang/qt/src/wkdrefreshjob_p.h
index 377350f3..60fdfedd 100644
--- a/lang/qt/src/wkdrefreshjob_p.h
+++ b/lang/qt/src/wkdrefreshjob_p.h
@@ -44,6 +44,7 @@ namespace QGpgME
struct WKDRefreshJobPrivate : public JobPrivate
{
std::vector<GpgME::Key> m_keys;
+ std::vector<GpgME::UserID> m_userIds;
};
}
diff --git a/lang/qt/tests/run-wkdrefreshjob.cpp b/lang/qt/tests/run-wkdrefreshjob.cpp
index 757ee899..c75718e6 100644
--- a/lang/qt/tests/run-wkdrefreshjob.cpp
+++ b/lang/qt/tests/run-wkdrefreshjob.cpp
@@ -38,6 +38,7 @@
#include <protocol.h>
#include <wkdrefreshjob.h>
+#include <QCommandLineParser>
#include <QCoreApplication>
#include <QDebug>
@@ -53,6 +54,36 @@ std::ostream &operator<<(std::ostream &os, const QString &s)
return os << s.toLocal8Bit().constData();
}
+struct CommandLineOptions {
+ bool allUserIds;
+ QString keyId;
+};
+
+CommandLineOptions parseCommandLine(const QStringList &arguments)
+{
+ CommandLineOptions options;
+
+ QCommandLineParser parser;
+ parser.setApplicationDescription("Test program for WKDRefreshJob");
+ parser.addHelpOption();
+ parser.addOptions({
+ {"all-userids", "Query WKD for all user IDs."},
+ });
+ parser.addPositionalArgument("key ID", "Key to refresh");
+
+ parser.process(arguments);
+
+ const auto args = parser.positionalArguments();
+ if (args.size() != 1) {
+ parser.showHelp(1);
+ }
+
+ options.allUserIds = parser.isSet("all-userids");
+ options.keyId = args[0];
+
+ return options;
+}
+
Key getOpenPGPKey(const QString &keyId, Error &err)
{
Key key;
@@ -74,22 +105,19 @@ int main(int argc, char **argv)
{
GpgME::initializeLibrary();
- if (argc != 2) {
- std::cerr << "Usage: " << argv[0] << " KEYID" << std::endl;
- return 1;
- }
-
QCoreApplication app{argc, argv};
- const auto keyId = qApp->arguments().last();
+ app.setApplicationName("run-wkdrefreshjob");
+
+ const auto options = parseCommandLine(app.arguments());
Error err;
- const auto key = getOpenPGPKey(keyId, err);
+ const auto key = getOpenPGPKey(options.keyId, err);
if (err.code() == GPG_ERR_AMBIGUOUS_NAME) {
- std::cerr << "Error: Multiple OpenPGP keys matching '" << keyId << "' found" << std::endl;
+ std::cerr << "Error: Multiple OpenPGP keys matching '" << options.keyId << "' found" << std::endl;
return 1;
}
if (key.isNull()) {
- std::cerr << "Error: No OpenPGP key matching '" << keyId << "' found" << std::endl;
+ std::cerr << "Error: No OpenPGP key matching '" << options.keyId << "' found" << std::endl;
return 1;
}
if (err) {
@@ -111,7 +139,11 @@ int main(int argc, char **argv)
}
qApp->quit();
});
- err = job->start({key});
+ if (options.allUserIds) {
+ err = job->start(key.userIDs());
+ } else {
+ err = job->start({key});
+ }
if (err) {
std::cerr << "Error: " << err.asString() << std::endl;
return 1;