17#include <config-libkleo.h>
19#include "keyresolver.h"
21#include "keyresolvercore.h"
23#include <libkleo/formatting.h>
24#include <libkleo/keycache.h>
25#include <libkleo/keygroup.h>
26#include <libkleo/newkeyapprovaldialog.h>
28#include <libkleo_debug.h>
30#include <gpgme++/key.h>
35class KeyResolver::Private
38 Private(
KeyResolver *qq,
bool enc,
bool sig, Protocol fmt,
bool allowMixed)
40 , mCore(enc, sig, fmt)
44 , mAllowMixed(allowMixed)
45 , mCache(KeyCache::instance())
46 , mDialogWindowFlags(
Qt::WindowFlags())
49 mCore.setAllowMixedProtocols(allowMixed);
55 void showApprovalDialog(KeyResolverCore::Result result,
QWidget *
parent);
56 void dialogAccepted();
59 KeyResolverCore mCore;
68 std::shared_ptr<const KeyCache> mCache;
69 std::unique_ptr<NewKeyApprovalDialog> mDialog;
71 Protocol mPreferredProtocol;
74static bool lessThan(
const Key &leftKey,
const Key &rightKey)
77 if (leftKey.isNull()) {
80 if (rightKey.isNull()) {
85 const auto leftNameAndOrEmail = Formatting::nameAndEmailForSummaryLine(leftKey);
86 const auto rightNameAndOrEmail = Formatting::nameAndEmailForSummaryLine(rightKey);
93 return strcmp(leftKey.primaryFingerprint(), rightKey.primaryFingerprint()) < 0;
100 if (!it.value().empty()) {
103 const auto keyMatchingAddress = mCache->findBestByMailBox(
address.toUtf8().constData(), solution.
protocol, KeyCache::KeyUsage::Encrypt);
104 if (!keyMatchingAddress.isNull()) {
107 const auto groupMatchingAddress = mCache->findGroup(address, solution.
protocol, KeyCache::KeyUsage::Encrypt);
108 if (!groupMatchingAddress.isNull()) {
109 qCDebug(LIBKLEO_LOG) << __func__ <<
"Expanding unresolved" <<
address <<
"with matching group";
110 const auto &groupKeys = groupMatchingAddress.keys();
111 std::vector<Key> keys;
112 keys.reserve(groupKeys.size());
113 std::copy(groupKeys.begin(), groupKeys.end(), std::back_inserter(keys));
114 std::sort(keys.begin(), keys.end(), lessThan);
122void KeyResolver::Private::showApprovalDialog(KeyResolverCore::Result result,
QWidget *
parent)
124 const auto preferredSolution = expandUnresolvedGroups(std::move(result.solution));
125 const auto alternativeSolution = expandUnresolvedGroups(std::move(result.alternative));
128 mDialog = std::make_unique<NewKeyApprovalDialog>(mEncrypt,
131 std::move(preferredSolution),
132 std::move(alternativeSolution),
141 Q_EMIT q->keysResolved(false, false);
146void KeyResolver::Private::dialogAccepted()
148 mResult = mDialog->result();
149 Q_EMIT q->keysResolved(
true,
false);
152void KeyResolver::start(
bool showApproval,
QWidget *parentWidget)
154 qCDebug(LIBKLEO_LOG) <<
"Starting ";
155 if (!d->mSign && !d->mEncrypt) {
157 return Q_EMIT keysResolved(
true,
true);
159 const auto result = d->mCore.resolve();
160 const bool success = (result.flags & KeyResolverCore::AllResolved);
161 if (success && !showApproval) {
162 d->mResult = std::move(result.solution);
163 Q_EMIT keysResolved(
true,
false);
165 }
else if (success) {
166 qCDebug(LIBKLEO_LOG) <<
"No need for the user showing approval anyway.";
169 d->showApprovalDialog(std::move(result), parentWidget);
172KeyResolver::KeyResolver(
bool encrypt,
bool sign, Protocol fmt,
bool allowMixed)
173 : d(new Private(this, encrypt, sign, fmt, allowMixed))
177Kleo::KeyResolver::~KeyResolver() =
default;
179void KeyResolver::setRecipients(
const QStringList &addresses)
181 d->mCore.setRecipients(addresses);
184void KeyResolver::setSender(
const QString &address)
186 d->mCore.setSender(address);
191 d->mCore.setOverrideKeys(overrides);
196 d->mCore.setSigningKeys(fingerprints);
206 d->mDialogWindowFlags = flags;
209void KeyResolver::setPreferredProtocol(Protocol proto)
211 d->mCore.setPreferredProtocol(proto);
214void KeyResolver::setMinimumValidity(
int validity)
216 d->mCore.setMinimumValidity(validity);
219#include "moc_keyresolver.cpp"
Kleo::Result setSigningKeys(const QStringList &fingerprints)
PostalAddress address(const QVariant &location)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QObject * parent() const const
QObject * sender() const const
int localeAwareCompare(QStringView s1, QStringView s2)
Solution represents the solution found by the KeyResolver.
GpgME::Protocol protocol
This property holds a hint at the protocol of the signing and encryption keys, i.e.
QMap< QString, std::vector< GpgME::Key > > encryptionKeys
This property contains the encryption keys to use for the different recipients.