diff options
| author | Ingo Klöcker <[email protected]> | 2023-08-21 14:01:37 +0000 | 
|---|---|---|
| committer | Ingo Klöcker <[email protected]> | 2023-08-21 16:06:52 +0000 | 
| commit | 2ad36f71144731f847c89b1f1e91f21c215cffa1 (patch) | |
| tree | 6fbef75aa42e52d07ef343660c5735d96027bb70 | |
| parent | doc: Fix interface changes (diff) | |
| download | gpgme-2ad36f71144731f847c89b1f1e91f21c215cffa1.tar.gz gpgme-2ad36f71144731f847c89b1f1e91f21c215cffa1.zip  | |
qt: Add job for refreshing OpenPGP keys via WKD
* lang/qt/src/wkdrefreshjob.cpp, lang/qt/src/wkdrefreshjob.h,
lang/qt/src/wkdrefreshjob_p.h, lang/qt/src/qgpgmewkdrefreshjob.cpp,
lang/qt/src/qgpgmewkdrefreshjob.h: New.
* lang/qt/src/protocol.h (class Protocol): Add pure virtual member
function wkdRefreshJob
* lang/qt/src/protocol_p.h (Protocol::wkdRefreshJob): ... and
implement it.
* lang/qt/src/Makefile.am: Update accordingly.
* lang/qt/tests/run-wkdrefreshjob.cpp: New.
* lang/qt/tests/Makefile.am: Add new test runner.
--
This job allows updating keys via WKD. Only user IDs that were
originally retrieved via WKD (i.e. which have origin WKD) are
considered.
GnuPG-bug-id: 6672
| -rw-r--r-- | NEWS | 6 | ||||
| -rw-r--r-- | lang/qt/src/Makefile.am | 12 | ||||
| -rw-r--r-- | lang/qt/src/protocol.h | 3 | ||||
| -rw-r--r-- | lang/qt/src/protocol_p.h | 12 | ||||
| -rw-r--r-- | lang/qt/src/qgpgmewkdrefreshjob.cpp | 147 | ||||
| -rw-r--r-- | lang/qt/src/qgpgmewkdrefreshjob.h | 64 | ||||
| -rw-r--r-- | lang/qt/src/wkdrefreshjob.cpp | 57 | ||||
| -rw-r--r-- | lang/qt/src/wkdrefreshjob.h | 71 | ||||
| -rw-r--r-- | lang/qt/src/wkdrefreshjob_p.h | 51 | ||||
| -rw-r--r-- | lang/qt/tests/Makefile.am | 4 | ||||
| -rw-r--r-- | lang/qt/tests/run-wkdrefreshjob.cpp | 121 | 
11 files changed, 545 insertions, 3 deletions
@@ -1,6 +1,12 @@  Noteworthy changes in version 1.22.1 (unreleased)  ------------------------------------------------- + * qt: Support refreshing keys via WKD.  [T6672] + + * Interface changes relative to the 1.22.0 release: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + qt: Protocol::wkdRefreshJob                NEW. + qt: WKDRefreshJob                          NEW.  Noteworthy changes in version 1.22.0 (2023-08-21)  ------------------------------------------------- diff --git a/lang/qt/src/Makefile.am b/lang/qt/src/Makefile.am index 3b3f1e80..b6929f26 100644 --- a/lang/qt/src/Makefile.am +++ b/lang/qt/src/Makefile.am @@ -56,6 +56,7 @@ qgpgme_sources = \      qgpgmesignencryptarchivejob.cpp \      qgpgmesignjob.cpp qgpgmesignkeyjob.cpp qgpgmeverifydetachedjob.cpp \      qgpgmeverifyopaquejob.cpp qgpgmewkdlookupjob.cpp threadedjobmixin.cpp \ +    qgpgmewkdrefreshjob.cpp \      qgpgmekeyformailboxjob.cpp qgpgme_debug.cpp \      qgpgmetofupolicyjob.cpp qgpgmequickjob.cpp \      defaultkeygenerationjob.cpp qgpgmewkspublishjob.cpp \ @@ -64,7 +65,8 @@ qgpgme_sources = \      signencryptjob.cpp \      signencryptarchivejob.cpp \      dn.cpp cryptoconfig.cpp wkdlookupresult.cpp \ -    util.cpp +    util.cpp \ +    wkdrefreshjob.cpp  # If you add one here make sure that you also add one in camelcase  qgpgme_headers= \ @@ -115,6 +117,7 @@ qgpgme_headers= \      tofupolicyjob.h \      wkdlookupjob.h \      wkdlookupresult.h \ +    wkdrefreshjob.h \      wkspublishjob.h \      gpgcardjob.h \      dn.h @@ -166,6 +169,7 @@ camelcase_headers= \      DefaultKeyGenerationJob \      WKDLookupJob \      WKDLookupResult \ +    WKDRefreshJob \      WKSPublishJob \      TofuPolicyJob \      GpgCardJob @@ -211,6 +215,7 @@ private_qgpgme_headers = \      qgpgmeverifydetachedjob.h \      qgpgmeverifyopaquejob.h \      qgpgmewkdlookupjob.h \ +    qgpgmewkdrefreshjob.h \      qgpgmekeyformailboxjob.h \      qgpgmewkspublishjob.h \      qgpgmetofupolicyjob.h \ @@ -220,7 +225,8 @@ private_qgpgme_headers = \      signencryptjob_p.h \      signencryptarchivejob_p.h \      threadedjobmixin.h \ -    util.h +    util.h \ +    wkdrefreshjob_p.h  qgpgme_moc_sources = \      abstractimportjob.moc \ @@ -275,6 +281,7 @@ qgpgme_moc_sources = \      qgpgmeverifydetachedjob.moc \      qgpgmeverifyopaquejob.moc \      qgpgmewkdlookupjob.moc \ +    qgpgmewkdrefreshjob.moc \      qgpgmewkspublishjob.moc \      tofupolicyjob.moc \      qgpgmetofupolicyjob.moc \ @@ -291,6 +298,7 @@ qgpgme_moc_sources = \      verifydetachedjob.moc \      verifyopaquejob.moc \      wkdlookupjob.moc \ +    wkdrefreshjob.moc \      keyformailboxjob.moc \      wkspublishjob.moc \      qgpgmekeyformailboxjob.moc \ diff --git a/lang/qt/src/protocol.h b/lang/qt/src/protocol.h index cbd93877..74fb921d 100644 --- a/lang/qt/src/protocol.h +++ b/lang/qt/src/protocol.h @@ -77,6 +77,7 @@ class GpgCardJob;  class ReceiveKeysJob;  class RevokeKeyJob;  class SetPrimaryUserIDJob; +class WKDRefreshJob;  /** The main entry point for QGpgME Comes in OpenPGP and SMIME(CMS) flavors.   * @@ -198,6 +199,8 @@ public:      virtual SignArchiveJob *signArchiveJob(bool armor = false) const = 0;      virtual SignEncryptArchiveJob *signEncryptArchiveJob(bool armor = false) const = 0;      virtual DecryptVerifyArchiveJob *decryptVerifyArchiveJob() const = 0; + +    virtual WKDRefreshJob *wkdRefreshJob() const = 0;  };  /** Obtain a reference to the OpenPGP Protocol. diff --git a/lang/qt/src/protocol_p.h b/lang/qt/src/protocol_p.h index fcb2b30a..b34b7a37 100644 --- a/lang/qt/src/protocol_p.h +++ b/lang/qt/src/protocol_p.h @@ -71,6 +71,7 @@  #include "qgpgmereceivekeysjob.h"  #include "qgpgmerevokekeyjob.h"  #include "qgpgmesetprimaryuseridjob.h" +#include "qgpgmewkdrefreshjob.h"  namespace  { @@ -557,6 +558,17 @@ public:          }          return nullptr;      } + +    QGpgME::WKDRefreshJob *wkdRefreshJob() const override +    { +        if (mProtocol != GpgME::OpenPGP) { +            return nullptr; +        } +        if (auto context = GpgME::Context::createForProtocol(mProtocol)) { +            return new QGpgME::QGpgMEWKDRefreshJob{context}; +        } +        return nullptr; +    }  };  } diff --git a/lang/qt/src/qgpgmewkdrefreshjob.cpp b/lang/qt/src/qgpgmewkdrefreshjob.cpp new file mode 100644 index 00000000..8bad1ef1 --- /dev/null +++ b/lang/qt/src/qgpgmewkdrefreshjob.cpp @@ -0,0 +1,147 @@ +/* +    qgpgmewkdrefreshjob.cpp + +    This file is part of qgpgme, the Qt API binding for gpgme +    Copyright (c) 2023 g10 Code GmbH +    Software engineering by Ingo Klöcker <[email protected]> + +    QGpgME is free software; you can redistribute it and/or +    modify it under the terms of the GNU General Public License as +    published by the Free Software Foundation; either version 2 of the +    License, or (at your option) any later version. + +    QGpgME is distributed in the hope that it will be useful, +    but WITHOUT ANY WARRANTY; without even the implied warranty of +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +    General Public License for more details. + +    You should have received a copy of the GNU General Public License +    along with this program; if not, write to the Free Software +    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + +    In addition, as a special exception, the copyright holders give +    permission to link the code of this program with any edition of +    the Qt library by Trolltech AS, Norway (or with modified versions +    of Qt that use the same license as Qt), and distribute linked +    combinations including the two.  You must obey the GNU General +    Public License in all respects for all of the code used other than +    Qt.  If you modify this file, you may extend this exception to +    your version of the file, but you are not obligated to do so.  If +    you do not wish to do so, delete this exception statement from +    your version. +*/ + +#ifdef HAVE_CONFIG_H + #include "config.h" +#endif + +#include "qgpgmewkdrefreshjob.h" + +#include "debug.h" +#include "qgpgme_debug.h" +#include "qgpgmekeylistjob.h" +#include "wkdrefreshjob_p.h" + +#include <context.h> + +#include <memory> + +using namespace QGpgME; +using namespace GpgME; + +namespace +{ + +class QGpgMEWKDRefreshJobPrivate : public WKDRefreshJobPrivate +{ +    QGpgMEWKDRefreshJob *q = nullptr; + +public: +    QGpgMEWKDRefreshJobPrivate(QGpgMEWKDRefreshJob *qq) +        : q{qq} +    { +    } + +    ~QGpgMEWKDRefreshJobPrivate() override = default; + +private: +    GpgME::Error startIt() override; + +    void startNow() override +    { +        q->run(); +    } +}; + +static QStringList toEmailAddressesOriginatingFromWKD(const std::vector<GpgME::Key> &keys) +{ +    const QStringList emails = std::accumulate(keys.begin(), keys.end(), QStringList{}, [](QStringList &emails, const Key &key) { +        const auto userIDs = key.userIDs(); +        emails = std::accumulate(std::begin(userIDs), std::end(userIDs), emails, [](QStringList &emails, const UserID &userID) { +            if (!userID.isRevoked() && !userID.addrSpec().empty() && userID.origin() == Key::OriginWKD) { +                emails.push_back(QString::fromStdString(userID.addrSpec())); +            } +            return emails; +        }); +        return emails; +    }); +    return emails; +} + +} + +QGpgMEWKDRefreshJob::QGpgMEWKDRefreshJob(Context *context) +    : mixin_type{context} +{ +    setJobPrivate(this, std::unique_ptr<QGpgMEWKDRefreshJobPrivate>{new QGpgMEWKDRefreshJobPrivate{this}}); +    lateInitialization(); +} + +QGpgMEWKDRefreshJob::~QGpgMEWKDRefreshJob() = default; + +static ImportResult locate_external_keys(Context *ctx, const std::vector<Key> &keys) +{ +    const auto emails = toEmailAddressesOriginatingFromWKD(keys); +    qCDebug(QGPGME_LOG) << __func__ << "locating external keys for" << emails; +    if (emails.empty()) { +        return ImportResult{}; +    } + +    Context::KeyListModeSaver saver{ctx}; +    ctx->setKeyListMode(GpgME::LocateExternal); +    ctx->setFlag("auto-key-locate", "clear,wkd"); +    std::vector<Key> dummy; +    auto job = std::unique_ptr<KeyListJob>{new QGpgMEKeyListJob{ctx}}; +    (void) job->exec(emails, false, dummy); +    qCDebug(QGPGME_LOG) << __func__ << "number of keys:" << dummy.size(); +    std::for_each(dummy.cbegin(), dummy.cend(), [](const Key &k) { +        qCDebug(QGPGME_LOG) << __func__ << toLogString(k).c_str(); +    }); +    const auto result = ctx->importResult(); +    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); +    } + +    q->run([=](Context *ctx) { +        return refresh_keys(ctx, m_keys); +    }); + +    return {}; +} + +#include "qgpgmewkdrefreshjob.moc" diff --git a/lang/qt/src/qgpgmewkdrefreshjob.h b/lang/qt/src/qgpgmewkdrefreshjob.h new file mode 100644 index 00000000..1b775aed --- /dev/null +++ b/lang/qt/src/qgpgmewkdrefreshjob.h @@ -0,0 +1,64 @@ +/* +    qgpgmewkdrefreshjob.h + +    This file is part of qgpgme, the Qt API binding for gpgme +    Copyright (c) 2023 g10 Code GmbH +    Software engineering by Ingo Klöcker <[email protected]> + +    QGpgME is free software; you can redistribute it and/or +    modify it under the terms of the GNU General Public License as +    published by the Free Software Foundation; either version 2 of the +    License, or (at your option) any later version. + +    QGpgME is distributed in the hope that it will be useful, +    but WITHOUT ANY WARRANTY; without even the implied warranty of +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +    General Public License for more details. + +    You should have received a copy of the GNU General Public License +    along with this program; if not, write to the Free Software +    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + +    In addition, as a special exception, the copyright holders give +    permission to link the code of this program with any edition of +    the Qt library by Trolltech AS, Norway (or with modified versions +    of Qt that use the same license as Qt), and distribute linked +    combinations including the two.  You must obey the GNU General +    Public License in all respects for all of the code used other than +    Qt.  If you modify this file, you may extend this exception to +    your version of the file, but you are not obligated to do so.  If +    you do not wish to do so, delete this exception statement from +    your version. +*/ + +#ifndef __QGPGME_QGPGMEWKDREFRESHJOB_H__ +#define __QGPGME_QGPGMEWKDREFRESHJOB_H__ + +#include "threadedjobmixin.h" +#include "wkdrefreshjob.h" + +#include <importresult.h> + +namespace QGpgME +{ + +class QGpgMEWKDRefreshJob +#ifdef Q_MOC_RUN +    : public WKDRefreshJob +#else +    : public _detail::ThreadedJobMixin<WKDRefreshJob, std::tuple<GpgME::ImportResult, QString, GpgME::Error>> +#endif +{ +    Q_OBJECT +#ifdef Q_MOC_RUN +public Q_SLOTS: +    void slotFinished(); +#endif +public: +    explicit QGpgMEWKDRefreshJob(GpgME::Context *context); +    ~QGpgMEWKDRefreshJob() override; +}; + +} + +#endif // __QGPGME_QGPGMEWKDREFRESHJOB_H__ diff --git a/lang/qt/src/wkdrefreshjob.cpp b/lang/qt/src/wkdrefreshjob.cpp new file mode 100644 index 00000000..37b990c8 --- /dev/null +++ b/lang/qt/src/wkdrefreshjob.cpp @@ -0,0 +1,57 @@ +/* +    wkdrefreshjob.cpp + +    This file is part of qgpgme, the Qt API binding for gpgme +    Copyright (c) 2023 g10 Code GmbH +    Software engineering by Ingo Klöcker <[email protected]> + +    QGpgME is free software; you can redistribute it and/or +    modify it under the terms of the GNU General Public License as +    published by the Free Software Foundation; either version 2 of the +    License, or (at your option) any later version. + +    QGpgME is distributed in the hope that it will be useful, +    but WITHOUT ANY WARRANTY; without even the implied warranty of +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +    General Public License for more details. + +    You should have received a copy of the GNU General Public License +    along with this program; if not, write to the Free Software +    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + +    In addition, as a special exception, the copyright holders give +    permission to link the code of this program with any edition of +    the Qt library by Trolltech AS, Norway (or with modified versions +    of Qt that use the same license as Qt), and distribute linked +    combinations including the two.  You must obey the GNU General +    Public License in all respects for all of the code used other than +    Qt.  If you modify this file, you may extend this exception to +    your version of the file, but you are not obligated to do so.  If +    you do not wish to do so, delete this exception statement from +    your version. +*/ + +#ifdef HAVE_CONFIG_H + #include "config.h" +#endif + +#include "wkdrefreshjob.h" +#include "wkdrefreshjob_p.h" + +using namespace QGpgME; + +WKDRefreshJob::WKDRefreshJob(QObject *parent) +    : AbstractImportJob{parent} +{ +} + +WKDRefreshJob::~WKDRefreshJob() = default; + +GpgME::Error WKDRefreshJob::start(const std::vector<GpgME::Key> &keys) +{ +    auto d = jobPrivate<WKDRefreshJobPrivate>(this); +    d->m_keys = keys; +    return d->startIt(); +} + +#include "wkdrefreshjob.moc" diff --git a/lang/qt/src/wkdrefreshjob.h b/lang/qt/src/wkdrefreshjob.h new file mode 100644 index 00000000..c3aec65f --- /dev/null +++ b/lang/qt/src/wkdrefreshjob.h @@ -0,0 +1,71 @@ +/* +    wkdrefreshjob.h + +    This file is part of qgpgme, the Qt API binding for gpgme +    Copyright (c) 2023 g10 Code GmbH +    Software engineering by Ingo Klöcker <[email protected]> + +    QGpgME is free software; you can redistribute it and/or +    modify it under the terms of the GNU General Public License as +    published by the Free Software Foundation; either version 2 of the +    License, or (at your option) any later version. + +    QGpgME is distributed in the hope that it will be useful, +    but WITHOUT ANY WARRANTY; without even the implied warranty of +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +    General Public License for more details. + +    You should have received a copy of the GNU General Public License +    along with this program; if not, write to the Free Software +    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + +    In addition, as a special exception, the copyright holders give +    permission to link the code of this program with any edition of +    the Qt library by Trolltech AS, Norway (or with modified versions +    of Qt that use the same license as Qt), and distribute linked +    combinations including the two.  You must obey the GNU General +    Public License in all respects for all of the code used other than +    Qt.  If you modify this file, you may extend this exception to +    your version of the file, but you are not obligated to do so.  If +    you do not wish to do so, delete this exception statement from +    your version. +*/ + +#ifndef __QGPGME_WKDREFRESHJOB_H__ +#define __QGPGME_WKDREFRESHJOB_H__ + +#include "abstractimportjob.h" +#include "qgpgme_export.h" + +#include <vector> + +namespace GpgME +{ +class Error; +class Key; +} + +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. + */ +class QGPGME_EXPORT WKDRefreshJob : public AbstractImportJob +{ +    Q_OBJECT +protected: +    explicit WKDRefreshJob(QObject *parent); +public: +    ~WKDRefreshJob() override; + +    /** +     * Starts a refresh of the \a keys. +     */ +    GpgME::Error start(const std::vector<GpgME::Key> &keys); +}; + +} + +#endif // __QGPGME_WKDREFRESHJOB_H__ diff --git a/lang/qt/src/wkdrefreshjob_p.h b/lang/qt/src/wkdrefreshjob_p.h new file mode 100644 index 00000000..377350f3 --- /dev/null +++ b/lang/qt/src/wkdrefreshjob_p.h @@ -0,0 +1,51 @@ +/* +    wkdrefreshjob_p.h + +    This file is part of qgpgme, the Qt API binding for gpgme +    Copyright (c) 2023 g10 Code GmbH +    Software engineering by Ingo Klöcker <[email protected]> + +    QGpgME is free software; you can redistribute it and/or +    modify it under the terms of the GNU General Public License as +    published by the Free Software Foundation; either version 2 of the +    License, or (at your option) any later version. + +    QGpgME is distributed in the hope that it will be useful, +    but WITHOUT ANY WARRANTY; without even the implied warranty of +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +    General Public License for more details. + +    You should have received a copy of the GNU General Public License +    along with this program; if not, write to the Free Software +    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + +    In addition, as a special exception, the copyright holders give +    permission to link the code of this program with any edition of +    the Qt library by Trolltech AS, Norway (or with modified versions +    of Qt that use the same license as Qt), and distribute linked +    combinations including the two.  You must obey the GNU General +    Public License in all respects for all of the code used other than +    Qt.  If you modify this file, you may extend this exception to +    your version of the file, but you are not obligated to do so.  If +    you do not wish to do so, delete this exception statement from +    your version. +*/ + +#ifndef __QGPGME_WKDREFRESHJOB_P_H__ +#define __QGPGME_WKDREFRESHJOB_P_H__ + +#include "job_p.h" + +#include <key.h> + +namespace QGpgME +{ + +struct WKDRefreshJobPrivate : public JobPrivate +{ +    std::vector<GpgME::Key> m_keys; +}; + +} + +#endif // __QGPGME_WKDREFRESHJOB_P_H__ diff --git a/lang/qt/tests/Makefile.am b/lang/qt/tests/Makefile.am index d9713d90..32ad6466 100644 --- a/lang/qt/tests/Makefile.am +++ b/lang/qt/tests/Makefile.am @@ -97,6 +97,7 @@ run_keyformailboxjob_SOURCES = run-keyformailboxjob.cpp  run_receivekeysjob_SOURCES = run-receivekeysjob.cpp  run_refreshkeysjob_SOURCES = run-refreshkeysjob.cpp  run_signarchivejob_SOURCES = run-signarchivejob.cpp +run_wkdrefreshjob_SOURCES = run-wkdrefreshjob.cpp  nodist_t_keylist_SOURCES = $(moc_files) @@ -112,7 +113,8 @@ noinst_PROGRAMS = \  	run-decryptverifyarchivejob \  	run-encryptarchivejob \  	run-importjob run-exportjob run-receivekeysjob run-refreshkeysjob \ -	run-signarchivejob +	run-signarchivejob \ +	run-wkdrefreshjob  CLEANFILES = secring.gpg pubring.gpg pubring.kbx trustdb.gpg dirmngr.conf \ diff --git a/lang/qt/tests/run-wkdrefreshjob.cpp b/lang/qt/tests/run-wkdrefreshjob.cpp new file mode 100644 index 00000000..757ee899 --- /dev/null +++ b/lang/qt/tests/run-wkdrefreshjob.cpp @@ -0,0 +1,121 @@ +/* +    run-wkdrefreshjob.cpp + +    This file is part of QGpgME's test suite. +    Copyright (c) 2023 g10 Code GmbH +    Software engineering by Ingo Klöcker <[email protected]> + +    QGpgME is free software; you can redistribute it and/or +    modify it under the terms of the GNU General Public License as +    published by the Free Software Foundation; either version 2 of the +    License, or (at your option) any later version. + +    QGpgME is distributed in the hope that it will be useful, +    but WITHOUT ANY WARRANTY; without even the implied warranty of +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +    General Public License for more details. + +    You should have received a copy of the GNU General Public License +    along with this program; if not, write to the Free Software +    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + +    In addition, as a special exception, the copyright holders give +    permission to link the code of this program with any edition of +    the Qt library by Trolltech AS, Norway (or with modified versions +    of Qt that use the same license as Qt), and distribute linked +    combinations including the two.  You must obey the GNU General +    Public License in all respects for all of the code used other than +    Qt.  If you modify this file, you may extend this exception to +    your version of the file, but you are not obligated to do so.  If +    you do not wish to do so, delete this exception statement from +    your version. +*/ + +#ifdef HAVE_CONFIG_H + #include "config.h" +#endif + +#include <protocol.h> +#include <wkdrefreshjob.h> + +#include <QCoreApplication> +#include <QDebug> + +#include <context.h> +#include <importresult.h> + +#include <iostream> + +using namespace GpgME; + +std::ostream &operator<<(std::ostream &os, const QString &s) +{ +    return os << s.toLocal8Bit().constData(); +} + +Key getOpenPGPKey(const QString &keyId, Error &err) +{ +    Key key; + +    auto ctx = Context::create(GpgME::OpenPGP); +    if (!ctx) { +        err = Error::fromCode(GPG_ERR_GENERAL); +        return key; +    } + +    key = ctx->key(keyId.toLatin1().constData(), err); +    if (err.code() == GPG_ERR_EOF) { +        err = Error{}; +    } +    return key; +} + +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(); + +    Error err; +    const auto key = getOpenPGPKey(keyId, err); +    if (err.code() == GPG_ERR_AMBIGUOUS_NAME) { +        std::cerr << "Error: Multiple OpenPGP keys matching '" << keyId << "' found" << std::endl; +        return 1; +    } +    if (key.isNull()) { +        std::cerr << "Error: No OpenPGP key matching '" << keyId << "' found" << std::endl; +        return 1; +    } +    if (err) { +        std::cerr << "Error while getting OpenPGP key: " << err.asString() << std::endl; +        return 1; +    } +    std::cout << "Refreshing OpenPGP key " << key.userID(0).id() << std::endl; + +    auto job = QGpgME::openpgp()->wkdRefreshJob(); +    if (!job) { +        std::cerr << "Error: Could not create job to refresh OpenPGP key" << std::endl; +        return 1; +    } +    QObject::connect(job, &QGpgME::WKDRefreshJob::result, &app, [](const GpgME::ImportResult &result, const QString &, const GpgME::Error &) { +        if (result.isNull()) { +            std::cout << "Empty result. Lookup via WKD failed or no user ID was originally retrieved via WKD." << std::endl; +        } else { +            std::cout << "Result: " << result << std::endl; +        } +        qApp->quit(); +    }); +    err = job->start({key}); +    if (err) { +        std::cerr << "Error: " << err.asString() << std::endl; +        return 1; +    } + +    return app.exec(); +}  | 
