16#include <config-libkleo.h>
18#include "keyrequester.h"
20#include "keyselectiondialog.h"
22#include <libkleo/algorithm.h>
23#include <libkleo/compliance.h>
24#include <libkleo/dn.h>
25#include <libkleo/formatting.h>
26#include <libkleo/keyhelpers.h>
28#include <KLocalizedString>
31#include <QGpgME/KeyListJob>
33#include <QApplication>
39#include <gpgme++/key.h>
40#include <gpgme++/keylistresult.h>
42using namespace QGpgME;
45Kleo::KeyRequester::KeyRequester(
unsigned int allowedKeys,
bool multipleKeys,
QWidget *parent)
47 , mOpenPGPBackend(nullptr)
48 , mSMIMEBackend(nullptr)
49 , mMulti(multipleKeys)
50 , mKeyUsage(allowedKeys)
57Kleo::KeyRequester::KeyRequester(
QWidget *parent)
59 , mOpenPGPBackend(nullptr)
60 , mSMIMEBackend(nullptr)
69void Kleo::KeyRequester::init()
72 hlay->setContentsMargins(0, 0, 0, 0);
74 if (DeVSCompliance::isCompliant()) {
75 mComplianceIcon =
new QLabel{
this};
76 mComplianceIcon->
setPixmap(Formatting::questionIcon().pixmap(22));
95 if (mComplianceIcon) {
96 hlay->addWidget(mComplianceIcon);
98 hlay->addWidget(mLabel, 1);
99 hlay->addWidget(mEraseButton);
100 hlay->addWidget(mDialogButton);
107 setAllowedKeys(mKeyUsage);
110Kleo::KeyRequester::~KeyRequester()
114const std::vector<GpgME::Key> &Kleo::KeyRequester::keys()
const
119const GpgME::Key &Kleo::KeyRequester::key()
const
121 static const GpgME::Key null = GpgME::Key::null;
125 return mKeys.front();
132 for (
auto it = keys.begin(); it != keys.end(); ++it) {
134 mKeys.push_back(*it);
144 mKeys.push_back(key);
149QString Kleo::KeyRequester::fingerprint()
const
158QStringList Kleo::KeyRequester::fingerprints()
const
161 for (
auto it = mKeys.begin(); it != mKeys.end(); ++it) {
163 if (
const char *fpr = it->primaryFingerprint()) {
178 startKeyListJob(fingerprints);
181void Kleo::KeyRequester::updateKeys()
184 if (mComplianceIcon) {
185 mComplianceIcon->setPixmap(Formatting::unavailableIcon().pixmap(22));
186 mComplianceIcon->setToolTip(
QString{});
191 if (mKeys.size() > 1) {
192 setMultipleKeysEnabled(
true);
197 for (std::vector<GpgME::Key>::const_iterator it = mKeys.begin(); it != mKeys.end(); ++it) {
205 if (
const char *uid = it->userID(0).id()) {
206 if (it->protocol() == GpgME::OpenPGP) {
212 toolTipText +=
xi18n(
"<placeholder>unknown</placeholder>");
216 if (mComplianceIcon) {
217 if (Kleo::all_of(mKeys, &Kleo::DeVSCompliance::keyIsCompliant)) {
218 mComplianceIcon->setPixmap(Formatting::successIcon().pixmap(22));
219 mComplianceIcon->setToolTip(DeVSCompliance::name(
true));
221 mComplianceIcon->setPixmap(Formatting::warningIcon().pixmap(22));
222 mComplianceIcon->setToolTip(DeVSCompliance::name(
false));
226 mLabel->setToolTip(toolTipText);
229#ifndef __KLEO_UI_SHOW_KEY_LIST_ERROR_H__
230#define __KLEO_UI_SHOW_KEY_LIST_ERROR_H__
231static void showKeyListError(
QWidget *parent,
const GpgME::Error &err)
235 "<qt><p>An error occurred while fetching "
236 "the keys from the backend:</p>"
237 "<p><b>%1</b></p></qt>",
238 Formatting::errorAsString(err));
244void Kleo::KeyRequester::startKeyListJob(
const QStringList &fingerprints)
246 if (!mSMIMEBackend && !mOpenPGPBackend) {
253 unsigned int count = 0;
255 if (!(*it).trimmed().isEmpty()) {
263 setKey(GpgME::Key::null);
267 if (mOpenPGPBackend) {
268 KeyListJob *job = mOpenPGPBackend->keyListJob(
false);
271 i18n(
"The OpenPGP backend does not support listing keys. "
272 "Check your installation."),
273 i18nc(
"@title:window",
"Key Listing Failed"));
275 connect(job, &KeyListJob::result,
this, &SigningKeyRequester::slotKeyListResult);
276 connect(job, &KeyListJob::nextKey,
this, &SigningKeyRequester::slotNextKey);
278 const GpgME::Error err =
279 job->start(fingerprints, mKeyUsage & Kleo::KeySelectionDialog::SecretKeys && !(mKeyUsage & Kleo::KeySelectionDialog::PublicKeys));
282 showKeyListError(
this, err);
290 KeyListJob *job = mSMIMEBackend->keyListJob(
false);
293 i18n(
"The S/MIME backend does not support listing keys. "
294 "Check your installation."),
295 i18nc(
"@title:window",
"Key Listing Failed"));
297 connect(job, &KeyListJob::result,
this, &SigningKeyRequester::slotKeyListResult);
298 connect(job, &KeyListJob::nextKey,
this, &SigningKeyRequester::slotNextKey);
300 const GpgME::Error err =
301 job->start(fingerprints, mKeyUsage & Kleo::KeySelectionDialog::SecretKeys && !(mKeyUsage & Kleo::KeySelectionDialog::PublicKeys));
304 showKeyListError(
this, err);
312 mEraseButton->setEnabled(
false);
313 mDialogButton->setEnabled(
false);
317void Kleo::KeyRequester::slotNextKey(
const GpgME::Key &key)
320 mTmpKeys.push_back(key);
324void Kleo::KeyRequester::slotKeyListResult(
const GpgME::KeyListResult &res)
327 showKeyListError(
this, res.error());
331 mEraseButton->setEnabled(
true);
332 mDialogButton->setEnabled(
true);
339void Kleo::KeyRequester::slotDialogButtonClicked()
341 KeySelectionDialog *dlg = mKeys.empty() ?
new KeySelectionDialog(mDialogCaption, mDialogMessage, mInitialQuery, mKeyUsage, mMulti,
false,
this)
342 : new KeySelectionDialog(mDialogCaption, mDialogCaption, mKeys, mKeyUsage, mMulti, false, this);
346 setKeys(dlg->selectedKeys());
348 setKey(dlg->selectedKey());
356void Kleo::KeyRequester::slotEraseButtonClicked()
358 if (!mKeys.empty()) {
365void Kleo::KeyRequester::setDialogCaption(
const QString &caption)
367 mDialogCaption = caption;
370void Kleo::KeyRequester::setDialogMessage(
const QString &msg)
372 mDialogMessage = msg;
375bool Kleo::KeyRequester::isMultipleKeysEnabled()
const
380void Kleo::KeyRequester::setMultipleKeysEnabled(
bool multi)
382 if (multi == mMulti) {
386 if (!multi && !mKeys.empty()) {
387 mKeys.erase(mKeys.begin() + 1, mKeys.end());
394unsigned int Kleo::KeyRequester::allowedKeys()
const
399void Kleo::KeyRequester::setAllowedKeys(
unsigned int keyUsage)
401 mKeyUsage = keyUsage;
402 mOpenPGPBackend =
nullptr;
403 mSMIMEBackend =
nullptr;
405 if (mKeyUsage & KeySelectionDialog::OpenPGPKeys) {
406 mOpenPGPBackend = openpgp();
408 if (mKeyUsage & KeySelectionDialog::SMIMEKeys) {
409 mSMIMEBackend = smime();
412 if (mOpenPGPBackend && !mSMIMEBackend) {
413 mDialogCaption =
i18n(
"OpenPGP Key Selection");
414 mDialogMessage =
i18n(
"Please select an OpenPGP key to use.");
415 }
else if (!mOpenPGPBackend && mSMIMEBackend) {
416 mDialogCaption =
i18n(
"S/MIME Key Selection");
417 mDialogMessage =
i18n(
"Please select an S/MIME key to use.");
419 mDialogCaption =
i18n(
"Key Selection");
420 mDialogMessage =
i18n(
"Please select an (OpenPGP or S/MIME) key to use.");
426 return mDialogButton;
434static inline unsigned int foo(
bool openpgp,
bool smime,
bool trusted,
bool valid)
436 unsigned int result = 0;
438 result |= Kleo::KeySelectionDialog::OpenPGPKeys;
441 result |= Kleo::KeySelectionDialog::SMIMEKeys;
444 result |= Kleo::KeySelectionDialog::TrustedKeys;
447 result |= Kleo::KeySelectionDialog::ValidKeys;
452static inline unsigned int encryptionKeyUsage(
bool openpgp,
bool smime,
bool trusted,
bool valid)
454 return foo(openpgp, smime, trusted, valid) | Kleo::KeySelectionDialog::EncryptionKeys | Kleo::KeySelectionDialog::PublicKeys;
457static inline unsigned int signingKeyUsage(
bool openpgp,
bool smime,
bool trusted,
bool valid)
459 return foo(openpgp, smime, trusted, valid) | Kleo::KeySelectionDialog::SigningKeys | Kleo::KeySelectionDialog::SecretKeys;
462Kleo::EncryptionKeyRequester::EncryptionKeyRequester(
bool multi,
unsigned int proto,
QWidget *parent,
bool onlyTrusted,
bool onlyValid)
463 :
KeyRequester(encryptionKeyUsage(proto & OpenPGP, proto & SMIME, onlyTrusted, onlyValid), multi, parent)
468Kleo::EncryptionKeyRequester::EncryptionKeyRequester(
QWidget *parent)
474Kleo::EncryptionKeyRequester::~EncryptionKeyRequester()
478void Kleo::EncryptionKeyRequester::setAllowedKeys(
unsigned int proto,
bool onlyTrusted,
bool onlyValid)
480 KeyRequester::setAllowedKeys(encryptionKeyUsage(proto & OpenPGP, proto & SMIME, onlyTrusted, onlyValid));
483Kleo::SigningKeyRequester::SigningKeyRequester(
bool multi,
unsigned int proto,
QWidget *parent,
bool onlyTrusted,
bool onlyValid)
484 :
KeyRequester(signingKeyUsage(proto & OpenPGP, proto & SMIME, onlyTrusted, onlyValid), multi, parent)
489Kleo::SigningKeyRequester::SigningKeyRequester(
QWidget *parent)
495Kleo::SigningKeyRequester::~SigningKeyRequester()
499void Kleo::SigningKeyRequester::setAllowedKeys(
unsigned int proto,
bool onlyTrusted,
bool onlyValid)
501 KeyRequester::setAllowedKeys(signingKeyUsage(proto & OpenPGP, proto & SMIME, onlyTrusted, onlyValid));
504void Kleo::KeyRequester::virtual_hook(
int,
void *)
507void Kleo::EncryptionKeyRequester::virtual_hook(
int id,
void *data)
509 KeyRequester::virtual_hook(
id, data);
511void Kleo::SigningKeyRequester::virtual_hook(
int id,
void *data)
513 KeyRequester::virtual_hook(
id, data);
516#include "moc_keyrequester.cpp"
Base class for SigningKeyRequester and EncryptionKeyRequester.
void setFingerprint(const QString &fingerprint)
Set the key by fingerprint.
void setFingerprints(const QStringList &fingerprints)
Set the keys by fingerprint.
void setKeys(const std::vector< GpgME::Key > &keys)
Preferred method to set a key for multi-KeyRequesters.
void setKey(const GpgME::Key &key)
Preferred method to set a key for non-multi-KeyRequesters.
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString xi18n(const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
void setFrameStyle(int style)
QIcon fromTheme(const QString &name)
void setPixmap(const QPixmap &)
void push_back(parameter_type value)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QString fromLatin1(QByteArrayView str)
QString fromUtf8(QByteArrayView str)
QString join(QChar separator) const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)