Commit 308f168d authored by Felix Tiede's avatar Felix Tiede Committed by Ingo Klöcker
Browse files

Rewrite as `Kleo::Commands::Command`.

See !16 (comment 427747)

Instead of using gpg-wks-binary on the commandline,
QGpgME::WKSPublishJob is now used, skipping creating, writing to,
reading from and finally deleting a temporary file on disk.
It also releases dependency on Libkleo to provide a path to the
gpg-wks-client binary.

Unlike the old version, successfully queueing a key publication request
mail does no longer produce an info box, a feature which might be
re-added.
parent cce3f38c
......@@ -3,7 +3,7 @@
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2008 Klarälvdalens Datakonsult AB
SPDX-FileCopyrightText: 2019-2022 Felix Tiede
SPDX-FileCopyrightText: 2022 Felix Tiede
SPDX-License-Identifier: GPL-2.0-or-later
*/
......@@ -13,9 +13,9 @@
#include "exportopenpgpcerttoprovidercommand.h"
#include "command_p.h"
#include <Libkleo/GnuPG>
#include <gpgme++/key.h>
#include <QGpgME/Protocol>
#include <QGpgME/WKSPublishJob>
#include <kidentitymanagement/identity.h>
#include <kidentitymanagement/identitymanager.h>
......@@ -30,143 +30,125 @@
using namespace Kleo;
using namespace Kleo::Commands;
using namespace GpgME;
using namespace QGpgME;
static const QString identityTransportForAddress(const QString &senderAddress) {
static const KIdentityManagement::IdentityManager *idManager = new KIdentityManagement::IdentityManager(true);
static const KIdentityManagement::IdentityManager *idManager = new KIdentityManagement::IdentityManager{true};
const KIdentityManagement::Identity identity = idManager->identityForAddress(senderAddress);
if (identity.isNull())
if (identity.isNull()) {
return idManager->defaultIdentity().transport();
else
} else {
return identity.transport();
}
}
ExportOpenPGPCertToProviderCommand::ExportOpenPGPCertToProviderCommand(QAbstractItemView *v, KeyListController *c)
: GnuPGProcessCommand(v, c)
: Command{v, c}
{
wksMail.open();
wksMail.close();
}
ExportOpenPGPCertToProviderCommand::ExportOpenPGPCertToProviderCommand(const UserID &uid)
: GnuPGProcessCommand(uid.parent()),
uid(uid)
: Command{uid.parent()},
uid{uid}
{
wksMail.open();
wksMail.close();
}
ExportOpenPGPCertToProviderCommand::~ExportOpenPGPCertToProviderCommand() {}
ExportOpenPGPCertToProviderCommand::~ExportOpenPGPCertToProviderCommand() = default;
bool ExportOpenPGPCertToProviderCommand::preStartHook(QWidget *parent) const
void ExportOpenPGPCertToProviderCommand::doStart()
{
const QString sender = senderAddress();
const QString transportName = identityTransportForAddress(sender);
if (transportName.isEmpty()) {
KMessageBox::error(parent,
KMessageBox::error(d->parentWidgetOrView(),
xi18nc("@warning",
"<para><email>%1</email> has no usable transport for mailing a key available, "
"WKS upload not possible.</para>", sender),
i18nc("@title:window", "OpenPGP Certificate Export"));
return false;
d->canceled();
return;
}
if (KMessageBox::warningContinueCancel(d->parentWidgetOrView(),
xi18nc("@info",
"<para>Not every mail provider supports WKS, so any key being "
"exported this way may fail individually.</para><para>If exported, "
"a confirmation request mail will be sent to <email>%1</email> "
"which needs to be acknowledged with a mail program to complete the "
"export process.</para><para><application>KMail</application> "
"can handle these mails, but not all mail programs can.</para>"
"<para>Once exported, the standard does not (yet) allow for "
"automated removal of a published key.</para>"
"<para>Are you sure you want to continue?</para>", sender),
i18nc("@title:window", "OpenPGP Certificate Export"),
KStandardGuiItem::cont(), KStandardGuiItem::cancel(),
QStringLiteral("warn-export-openpgp-wks-unsupported"))
== KMessageBox::Continue) {
auto wksJob = QGpgME::openpgp()->wksPublishJob();
connect(wksJob, &QGpgME::WKSPublishJob::result, this, &ExportOpenPGPCertToProviderCommand::wksJobResult);
wksJob->startCreate(d->key().primaryFingerprint(), senderAddress());
} else {
d->canceled();
}
return KMessageBox::warningContinueCancel(parent,
xi18nc("@info",
"<para>Not every mail provider supports WKS, so any key being "
"exported this way may fail individually.</para><para>If exported, "
"a confirmation request mail will be sent to <email>%1</email> "
"which needs to be acknowledged with a mail program to complete the "
"export process.</para><para><application>KMail</application> "
"can handle these mails, but not all mail programs can.</para>"
"<para>Once exported, the standard does not (yet) allow for "
"automated removal of a published key.</para>"
"<para>Are you sure you want to continue?</para>", sender),
i18nc("@title:window", "OpenPGP Certificate Export"),
KStandardGuiItem::cont(), KStandardGuiItem::cancel(),
QStringLiteral("warn-export-openpgp-wks-unsupported"))
== KMessageBox::Continue;
}
void ExportOpenPGPCertToProviderCommand::postSuccessHook(QWidget *parent)
void ExportOpenPGPCertToProviderCommand::doCancel()
{
}
void ExportOpenPGPCertToProviderCommand::wksJobResult(const GpgME::Error &error, const QByteArray &returnedData, const QByteArray &returnedError)
{
if (error) {
KMessageBox::error(d->parentWidgetOrView(),
xi18nc("@error",
"<para>An error occurred while trying to export OpenPGP certificates.</para> "
"<para>The output from GnuPG WKS client was: <message>%1</message></para>",
QString::fromUtf8(returnedError)),
i18nc("@title:window", "OpenPGP Certificate Export"));
d->canceled();
return;
}
MailTransport::Transport *transport = MailTransport::TransportManager::self()->transportByName(
identityTransportForAddress(senderAddress()));
if (!transport)
if (!transport) {
d->canceled();
return;
}
wksMail.open();
KMime::Message *msg = new KMime::Message();
KMime::Message *msg = new KMime::Message;
msg->setContent(KMime::CRLFtoLF(wksMail.readAll()));
msg->setContent(KMime::CRLFtoLF(returnedData));
msg->parse();
wksMail.close();
MailTransport::MessageQueueJob *job = new MailTransport::MessageQueueJob(parent);
MailTransport::MessageQueueJob *job = new MailTransport::MessageQueueJob(d->parentWidgetOrView());
job->transportAttribute().setTransportId(transport->id());
job->addressAttribute().setFrom(msg->from()->asUnicodeString());
job->addressAttribute().setTo(msg->to()->displayNames());
job->setMessage(KMime::Message::Ptr(msg));
job->setMessage(KMime::Message::Ptr{msg});
connect(job, &MailTransport::MessageQueueJob::result, this, [this](const KJob *mailJob) {
if (mailJob->error()) {
KMessageBox::error((QWidget *) mailJob->parent(),
KMessageBox::error(d->parentWidgetOrView(),
xi18nc("@error",
"<para>An error occurred when creating the mail to publish key:</para>"
"<para>%1</para>", mailJob->errorString()),
"<message>%1</message>", mailJob->errorString()),
i18nc("@title:window", "OpenPGP Certificate Export"));
d->canceled();
} else {
d->finished();
}
});
job->start();
}
QStringList ExportOpenPGPCertToProviderCommand::arguments() const
{
QStringList result;
result << gpgWksClientPath();
result << QStringLiteral("--output") << wksMail.fileName();
result << QStringLiteral("--create");
result << QString::fromUtf8(d->keys().at(0).primaryFingerprint());
result << senderAddress();
return result;
}
QString ExportOpenPGPCertToProviderCommand::errorCaption() const
{
return i18nc("@title:window", "OpenPGP Certificate Export Error");
}
QString ExportOpenPGPCertToProviderCommand::successCaption() const
{
return i18nc("@title:window", "OpenPGP Certificate Export Finished");
}
QString ExportOpenPGPCertToProviderCommand::crashExitMessage(const QStringList &args) const
{
return xi18nc("@info",
"<para>The GPG process that tried to export OpenPGP certificates "
"ended prematurely because of an unexpected error.</para>"
"<para>Please check the output of <icode>%1</icode> for details.</para>", args.join(QLatin1Char(' ')));
}
QString ExportOpenPGPCertToProviderCommand::errorExitMessage(const QStringList &args) const
{
return xi18nc("@info",
"<para>An error occurred while trying to export OpenPGP certificates.</para> "
"<para>The output from <command>%1</command> was: <message>%2</message></para>",
args[0], errorString());
}
QString ExportOpenPGPCertToProviderCommand::successMessage(const QStringList&) const
{
return i18nc("@info", "OpenPGP certificates exported successfully.");
}
QString ExportOpenPGPCertToProviderCommand::senderAddress() const
{
if (uid.isNull())
return QString::fromUtf8(d->keys().at(0).userID(0).addrSpec().data());
else
return QString::fromUtf8(uid.addrSpec().data());
if (uid.isNull()) {
return QString::fromUtf8(d->key().userID(0).addrSpec().data());
} else {
return QString::fromUtf8(uid.addrSpec().data());
}
}
/* -*- mode: c++; c-basic-offset:4 -*-
commands/exportopenpgpcertstoservercommand.h
commands/exportopenpgpcerttoprovidercommand.h
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2008 Klarälvdalens Datakonsult AB
SPDX-FileCopyrightText: 2019 Felix Tiede
SPDX-FileCopyrightText: 2022 Felix Tiede
SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include <commands/gnupgprocesscommand.h>
#include <QtCore/QTemporaryFile>
#include <commands/command.h>
#include <gpgme++/key.h>
......@@ -21,7 +19,7 @@ namespace Kleo
namespace Commands
{
class ExportOpenPGPCertToProviderCommand : public GnuPGProcessCommand
class ExportOpenPGPCertToProviderCommand : public Command
{
Q_OBJECT
public:
......@@ -35,24 +33,16 @@ public:
return OnlyOneKey | NeedSecretKey | MustBeOpenPGP;
}
private:
bool preStartHook(QWidget *) const override;
void postSuccessHook(QWidget *) override;
QStringList arguments() const override;
private Q_SLOTS:
void wksJobResult(const GpgME::Error &, const QByteArray &, const QByteArray &);
QString errorCaption() const override;
QString successCaption() const override;
QString crashExitMessage(const QStringList &) const override;
QString errorExitMessage(const QStringList &) const override;
QString successMessage(const QStringList &) const override;
private:
void doStart() override;
void doCancel() override;
QString senderAddress() const;
GpgME::UserID uid;
QTemporaryFile wksMail;
};
}
......
......@@ -97,7 +97,6 @@ public:
void webOfTrustClicked();
void exportClicked();
void addUserID();
void exportUserIDToProvider();
void changePassphrase();
void changeExpiration();
void keysMayHaveChanged();
......@@ -647,16 +646,6 @@ void CertificateDetailsWidget::Private::addUserID()
cmd->start();
}
void CertificateDetailsWidget::Private::exportUserIDToProvider()
{
auto userID = key.userID(0);
auto item = ui.userIDTable->currentItem();
if (item) {
userID = item->data(0, Qt::UserRole).value<GpgME::UserID>();
}
}
namespace
{
void ensureThatKeyDetailsAreLoaded(GpgME::Key &key)
......
......@@ -3,7 +3,7 @@
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2007 Klarälvdalens Datakonsult AB
SPDX-FileCopyrightText: 2019-2022 Felix Tiede
SPDX-FileCopyrightText: 2022 Felix Tiede
SPDX-License-Identifier: GPL-2.0-or-later
*/
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment