Commit 697dd515 authored by Ingo Klöcker's avatar Ingo Klöcker
Browse files

Allow revoking a specific certification via context menu

This adds a context menu for certifications to the certifications overview
allowing the user to show the details of the certification key (previously
only available via doubleclick) and to revoke the certification (if it
is still valid and if it was made with one of the user's keys).

GnuPG-bug-id: 5094
parent a43332bc
Pipeline #40353 failed with stage
in 10 minutes and 27 seconds
......@@ -18,12 +18,12 @@
#include "dialogs/revokecertificationdialog.h"
#include <Libkleo/Formatting>
#include <Libkleo/KeyCache>
#include <QGpgME/Protocol>
#include <QGpgME/QuickJob>
#include <gpgme++/engineinfo.h>
#include <gpgme++/key.h>
#include <KLocalizedString>
......@@ -62,6 +62,7 @@ private:
void createJob();
private:
Key certificationKey;
Key certificationTarget;
std::vector<UserID> uids;
QPointer<RevokeCertificationDialog> dialog;
......@@ -186,6 +187,14 @@ RevokeCertificationCommand::RevokeCertificationCommand(const GpgME::UserID &uid)
d->init();
}
RevokeCertificationCommand::RevokeCertificationCommand(const GpgME::UserID::Signature &signature)
: Command(signature.parent().parent(), new Private(this, nullptr))
{
std::vector<UserID>(1, signature.parent()).swap(d->uids);
d->certificationKey = KeyCache::instance()->findByKeyIDOrFingerprint(signature.signerKeyID());
d->init();
}
RevokeCertificationCommand::~RevokeCertificationCommand()
{
qCDebug(KLEOPATRA_LOG) << "~RevokeCertificationCommand()";
......@@ -222,6 +231,9 @@ void RevokeCertificationCommand::doStart()
if (!d->uids.empty()) {
d->dialog->setSelectedUserIDs(d->uids);
}
if (!d->certificationKey.isNull()) {
d->dialog->setSelectedCertificationKey(d->certificationKey);
}
d->dialog->show();
}
......
......@@ -13,10 +13,7 @@
#include <commands/command.h>
namespace GpgME
{
class UserID;
}
#include <gpgme++/key.h>
namespace Kleo
{
......@@ -29,6 +26,7 @@ class RevokeCertificationCommand : public Command
public:
explicit RevokeCertificationCommand(QAbstractItemView *view, KeyListController *parent);
explicit RevokeCertificationCommand(const GpgME::UserID &uid);
explicit RevokeCertificationCommand(const GpgME::UserID::Signature &signature);
~RevokeCertificationCommand() override;
/* reimp */ static Restrictions restrictions()
......
......@@ -127,6 +127,11 @@ std::vector<GpgME::UserID> RevokeCertificationDialog::selectedUserIDs() const
return d->mainWidget->selectedUserIDs();
}
void Kleo::RevokeCertificationDialog::setSelectedCertificationKey(const GpgME::Key &key)
{
d->mainWidget->setCertificationKey(key);
}
Key RevokeCertificationDialog::selectedCertificationKey() const
{
return d->mainWidget->certificationKey();
......
......@@ -35,6 +35,7 @@ public:
void setSelectedUserIDs(const std::vector<GpgME::UserID> &uids);
std::vector<GpgME::UserID> selectedUserIDs() const;
void setSelectedCertificationKey(const GpgME::Key &key);
GpgME::Key selectedCertificationKey() const;
bool sendToServer() const;
......
......@@ -246,6 +246,11 @@ std::vector<GpgME::UserID> RevokeCertificationWidget::selectedUserIDs() const
return d->mUserIDModel.checkedUserIDs();
}
void RevokeCertificationWidget::setCertificationKey(const GpgME::Key &key)
{
d->mCertificationKeySelect->setDefaultKey(QString::fromLatin1(key.primaryFingerprint()));
}
GpgME::Key RevokeCertificationWidget::certificationKey() const
{
return d->mCertificationKeySelect->currentKey();
......
......@@ -43,6 +43,9 @@ public:
/* The user ids whose certifications shall be revoked */
std::vector<GpgME::UserID> selectedUserIDs() const;
/* Set the selected certification key. Default: last used key */
void setCertificationKey(const GpgME::Key &key);
/* The selected certification key */
GpgME::Key certificationKey() const;
......
/* SPDX-FileCopyrightText: 2017 Intevation GmbH
/*
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2017 Intevation GmbH
SPDX-FileCopyrightText: 2020 g10 Code GmbH
SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
SPDX-License-Identifier: GPL-2.0-or-later
*/
......@@ -18,6 +22,7 @@
#include <QGpgME/Protocol>
#include <QGpgME/KeyListJob>
#include <Libkleo/KeyCache>
#include <Libkleo/UserIDListModel>
#include "kleopatra_debug.h"
......@@ -122,6 +127,50 @@ public:
}
}
void addActionsForSignature(QMenu *menu, const GpgME::UserID::Signature &signature)
{
menu->addAction(QIcon::fromTheme(QStringLiteral("dialog-information")),
i18n("Show Certificate Details..."),
q, [this, signature]() {
auto cmd = Command::commandForQuery(QString::fromUtf8(signature.signerKeyID()));
cmd->setParentWId(q->winId());
cmd->start();
});
if (Kleo::Commands::RevokeCertificationCommand::isSupported()) {
auto action = menu->addAction(QIcon::fromTheme(QStringLiteral("view-certificate-revoke")),
i18n("Revoke Certification..."),
q, [this, signature]() {
auto cmd = new Kleo::Commands::RevokeCertificationCommand(signature);
cmd->setParentWidget(q);
certificationsTV->setEnabled(false);
connect(cmd, &Kleo::Commands::RevokeCertificationCommand::finished,
q, [this]() {
certificationsTV->setEnabled(true);
// Trigger an update when done
q->setKey(key);
});
cmd->start();
});
const auto certificationKey = KeyCache::instance()->findByKeyIDOrFingerprint(signature.signerKeyID());
const bool isSelfSignature = qstrcmp(signature.parent().parent().keyID(), signature.signerKeyID()) == 0;
action->setEnabled(!isSelfSignature && certificationKey.hasSecret() && !signature.isRevokation() && !signature.isExpired() && !signature.isInvalid());
if (isSelfSignature) {
action->setToolTip(i18n("Revokation of self-certifications is currently not possible."));
} else if (!certificationKey.hasSecret()) {
action->setToolTip(i18n("You cannot revoke this certification because it wasn't made with one of your keys (or the required secret key is missing)."));
} else if (signature.isRevokation()) {
action->setToolTip(i18n("You cannot revoke this revokation certification. (But you can re-certify the corresponding user ID.)"));
} else if (signature.isExpired()) {
action->setToolTip(i18n("You cannot revoke this expired certification."));
} else if (signature.isInvalid()) {
action->setToolTip(i18n("You cannot revoke this invalid certification."));
}
if (!action->isEnabled()) {
menu->setToolTipsVisible(true);
}
}
}
void contextMenuRequested(const QPoint &p)
{
const auto index = certificationsTV->indexAt(p);
......@@ -136,6 +185,9 @@ public:
if (!userID.isNull()) {
addActionsForUserID(menu, userID);
}
else if (!signature.isNull()) {
addActionsForSignature(menu, signature);
}
connect(menu, &QMenu::aboutToHide, menu, &QObject::deleteLater);
menu->popup(certificationsTV->viewport()->mapToGlobal(p));
}
......
Markdown is supported
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