10#include <config-libkleo.h>
12#include "keyfiltermanager.h"
14#include "defaultkeyfilter.h"
15#include "kconfigbasedkeyfilter.h"
18#include <libkleo/algorithm.h>
19#include <libkleo/compliance.h>
20#include <libkleo/gnupg.h>
21#include <libkleo/keyhelpers.h>
23#include <libkleo_debug.h>
26#include <KConfigGroup>
27#include <KLocalizedString>
28#include <KSharedConfig>
30#include <QAbstractListModel>
31#include <QCoreApplication>
34#include <QRegularExpression>
49 KeyFilterManager::Private *m_keyFilterManagerPrivate;
52 explicit Model(KeyFilterManager::Private *p)
54 , m_keyFilterManagerPrivate(p)
67 AllCertificatesKeyFilter()
70 setSpecificity(UINT_MAX);
71 setName(
i18nc(
"All Certificates",
"All"));
72 setDescription(
i18n(
"All certificates"));
73 setId(QStringLiteral(
"all-certificates"));
74 setMatchContexts(Filtering);
81 MyCertificatesKeyFilter()
85 setSpecificity(UINT_MAX - 1);
87 setName(
i18nc(
"My own Certificates",
"My Own"));
88 setDescription(
i18n(
"My own certificates"));
89 setId(QStringLiteral(
"my-certificates"));
90 setMatchContexts(AnyMatchContext);
98 FullCertificatesKeyFilter()
102 setValidity(IsAtLeast);
103 setValidityReferenceLevel(UserID::Full);
104 setSpecificity(UINT_MAX - 3);
106 setName(
i18nc(
"Certified Certificates",
"Certified"));
107 setDescription(
i18n(
"Certificates for which the primary user ID is certified"));
108 setId(QStringLiteral(
"trusted-certificates"));
109 setMatchContexts(Filtering);
116 OtherCertificatesKeyFilter()
119 setHasSecret(NotSet);
120 setValidity(IsAtMost);
121 setValidityReferenceLevel(UserID::Marginal);
122 setSpecificity(UINT_MAX - 5);
124 setName(
i18nc(
"Not Certified Certificates",
"Not Certified"));
125 setDescription(
i18n(
"Certificates for which the primary user ID is not certified"));
126 setId(QStringLiteral(
"other-certificates"));
127 setMatchContexts(Filtering);
136 UncertifiedOpenPGPKeysFilter()
139 setSpecificity(UINT_MAX - 6);
140 setName(
i18nc(
"Certificates to certify by the user",
"To Certify"));
141 setDescription(
i18n(
"Certificates that are not fully certified and that you may want to certify yourself"));
142 setId(QStringLiteral(
"not-certified-certificates"));
144 setMatchContexts(Filtering);
148 bool matches(
const Key &key, MatchContexts contexts)
const override
150 return DefaultKeyFilter::matches(key, contexts) && !Kleo::allUserIDsHaveFullValidity(key);
152 bool matches(
const UserID &userID, MatchContexts contexts)
const override
154 return DefaultKeyFilter::matches(userID.parent(), contexts) && userID.validity() < UserID::Full;
166 setSpecificity(UINT_MAX - 4);
168 setName(
i18nc(
"Not Fully Certified Certificates",
"Not Fully Certified"));
169 setDescription(
i18n(
"Certificates for which not all user IDs are certified"));
170 setId(QStringLiteral(
"not-validated-certificates"));
171 setMatchContexts(Filtering);
173 bool matches(
const Key &key, MatchContexts contexts)
const override
175 return DefaultKeyFilter::matches(key, contexts) && !Kleo::allUserIDsHaveFullValidity(key);
177 bool matches(
const UserID &userID, MatchContexts contexts)
const override
179 return DefaultKeyFilter::matches(userID.parent(), contexts) && userID.validity() < UserID::Full;
188 KeyFullyCertifiedFilter()
191 setSpecificity(UINT_MAX - 2);
192 setName(
i18nc(
"Fully Certified Certificates",
"Fully Certified"));
193 setDescription(
i18n(
"Certificates for which all user IDs are certified"));
194 setId(QStringLiteral(
"full-certificates"));
195 setMatchContexts(Filtering);
197 bool matches(
const Key &key, MatchContexts contexts)
const override
199 return DefaultKeyFilter::matches(key, contexts) && Kleo::allUserIDsHaveFullValidity(key);
201 bool matches(
const UserID &userID, MatchContexts contexts)
const override
203 return DefaultKeyFilter::matches(userID.parent(), contexts) && userID.validity() >= UserID::Full;
207static std::vector<std::shared_ptr<KeyFilter>> defaultFilters()
210 std::shared_ptr<KeyFilter>(
new MyCertificatesKeyFilter),
211 std::shared_ptr<KeyFilter>(
new FullCertificatesKeyFilter),
212 std::shared_ptr<KeyFilter>(
new OtherCertificatesKeyFilter),
213 std::shared_ptr<KeyFilter>(
new AllCertificatesKeyFilter),
214 std::shared_ptr<KeyFilter>(
new UncertifiedOpenPGPKeysFilter),
215 std::shared_ptr<KeyFilter>(
new KeyFullyCertifiedFilter),
216 std::shared_ptr<KeyFilter>(
new KeyNotValidFilter),
220class KeyFilterManager::Private
230 model.beginResetModel();
232 model.endResetModel();
235 std::vector<std::shared_ptr<KeyFilter>> filters;
237 GpgME::Protocol protocol = GpgME::UnknownProtocol;
240KeyFilterManager *KeyFilterManager::mSelf =
nullptr;
242KeyFilterManager::KeyFilterManager(
QObject *parent)
254KeyFilterManager::~KeyFilterManager()
262KeyFilterManager *KeyFilterManager::instance()
265 mSelf =
new KeyFilterManager();
270void KeyFilterManager::alwaysFilterByProtocol(GpgME::Protocol protocol)
272 if (protocol != d->protocol) {
273 d->protocol = protocol;
278const std::shared_ptr<KeyFilter> &KeyFilterManager::filterMatching(
const Key &key,
KeyFilter::MatchContexts contexts)
const
280 const auto it = std::find_if(d->filters.cbegin(), d->filters.cend(), [&key, contexts](
const std::shared_ptr<KeyFilter> &filter) {
281 return filter->matches(key, contexts);
283 if (it != d->filters.cend()) {
286 static const std::shared_ptr<KeyFilter> null;
290std::vector<std::shared_ptr<KeyFilter>> KeyFilterManager::filtersMatching(
const Key &key,
KeyFilter::MatchContexts contexts)
const
292 std::vector<std::shared_ptr<KeyFilter>> result;
293 result.reserve(d->filters.size());
294 std::remove_copy_if(d->filters.begin(), d->filters.end(), std::back_inserter(result), [&key, contexts](
const std::shared_ptr<KeyFilter> &filter) {
295 return !filter->matches(key, contexts);
302static const auto byDecreasingSpecificity = [](
const std::shared_ptr<KeyFilter> &lhs,
const std::shared_ptr<KeyFilter> &rhs) {
303 return lhs->specificity() > rhs->specificity();
307void KeyFilterManager::reload()
311 d->filters = defaultFilters();
315 const bool ignoreDeVs = !DeVSCompliance::isCompliant();
318 if (cfg.hasKey(
"is-de-vs") && ignoreDeVs) {
322 d->filters.push_back(std::shared_ptr<KeyFilter>(
new KConfigBasedKeyFilter(cfg)));
324 std::stable_sort(d->filters.begin(), d->filters.end(), byDecreasingSpecificity);
326 if (d->protocol != GpgME::UnknownProtocol) {
328 const auto conflictingValue = (d->protocol == GpgME::OpenPGP) ? DefaultKeyFilter::NotSet :
DefaultKeyFilter::Set;
329 Kleo::erase_if(d->filters, [conflictingValue](
const auto &f) {
330 const auto filter = std::dynamic_pointer_cast<DefaultKeyFilter>(f);
332 return filter->isOpenPGP() == conflictingValue;
335 const auto isOpenPGPValue = (d->protocol == GpgME::OpenPGP) ? DefaultKeyFilter::Set :
DefaultKeyFilter::NotSet;
336 std::for_each(std::begin(d->filters), std::end(d->filters), [isOpenPGPValue](
auto &f) {
337 const auto filter = std::dynamic_pointer_cast<DefaultKeyFilter>(f);
339 return filter->setIsOpenPGP(isOpenPGPValue);
342 qCDebug(LIBKLEO_LOG) <<
"KeyFilterManager::" << __func__ <<
"final filter count is" << d->filters.size();
350const std::shared_ptr<KeyFilter> &KeyFilterManager::keyFilterByID(
const QString &
id)
const
352 const auto it = std::find_if(d->filters.begin(), d->filters.end(), [
id](
const std::shared_ptr<KeyFilter> &filter) {
353 return filter->id() == id;
355 if (it != d->filters.end()) {
358 static const std::shared_ptr<KeyFilter> null;
362const std::shared_ptr<KeyFilter> &KeyFilterManager::fromModelIndex(
const QModelIndex &idx)
const
364 if (!idx.
isValid() || idx.
model() != &d->model || idx.
row() < 0 ||
static_cast<unsigned>(idx.
row()) >= d->filters.size()) {
365 static const std::shared_ptr<KeyFilter> null;
368 return d->filters[idx.
row()];
371QModelIndex KeyFilterManager::toModelIndex(
const std::shared_ptr<KeyFilter> &kf)
const
376 const auto pair = std::equal_range(d->filters.cbegin(), d->filters.cend(), kf, byDecreasingSpecificity);
377 const auto it = std::find(pair.first, pair.second, kf);
378 if (it != pair.second) {
379 return d->model.index(it - d->filters.begin());
387 return m_keyFilterManagerPrivate->filters.size();
392 if (!idx.
isValid() || idx.
model() !=
this || idx.
row() < 0 ||
static_cast<unsigned>(idx.
row()) > m_keyFilterManagerPrivate->filters.size()) {
396 const auto filter = m_keyFilterManagerPrivate->filters[idx.
row()];
405 return filter->description();
407 case KeyFilterManager::FilterIdRole:
410 case KeyFilterManager::FilterMatchContextsRole:
418static KeyFilter::FontDescription
419get_fontdescription(
const std::vector<std::shared_ptr<KeyFilter>> &filters,
const Key &key,
const KeyFilter::FontDescription &initial)
421 return kdtools::accumulate_if(
424 [&key](
const std::shared_ptr<KeyFilter> &filter) {
425 return filter->matches(key, KeyFilter::Appearance);
428 [](
const KeyFilter::FontDescription &lhs,
const std::shared_ptr<KeyFilter> &rhs) {
429 return lhs.resolve(rhs->fontDescription());
433QFont KeyFilterManager::font(
const Key &key,
const QFont &baseFont)
const
435 const KeyFilter::FontDescription fd = get_fontdescription(d->filters, key, KeyFilter::FontDescription());
437 return fd.font(baseFont);
440static QColor get_color(
const std::vector<std::shared_ptr<KeyFilter>> &filters,
const Key &key,
QColor (
KeyFilter::*fun)() const)
442 const auto it = std::find_if(filters.cbegin(), filters.cend(), [&fun, &key](
const std::shared_ptr<KeyFilter> &filter) {
443 return filter->matches(key, KeyFilter::Appearance) && (filter.get()->*fun)().isValid();
445 if (it == filters.cend()) {
448 return (it->get()->*fun)();
452static QColor get_color(
const std::vector<std::shared_ptr<KeyFilter>> &filters,
const UserID &userID,
QColor (
KeyFilter::*fun)() const)
454 const auto it = std::find_if(filters.cbegin(), filters.cend(), [&fun, &userID](
const std::shared_ptr<KeyFilter> &filter) {
455 return filter->matches(userID, KeyFilter::Appearance) && (filter.get()->*fun)().isValid();
457 if (it == filters.cend()) {
460 return (it->get()->*fun)();
464static QString get_string(
const std::vector<std::shared_ptr<KeyFilter>> &filters,
const Key &key,
QString (
KeyFilter::*fun)() const)
466 const auto it = std::find_if(filters.cbegin(), filters.cend(), [&fun, &key](
const std::shared_ptr<KeyFilter> &filter) {
467 return filter->matches(key, KeyFilter::Appearance) && !(filter.get()->*fun)().isEmpty();
469 if (it == filters.cend()) {
472 return (*it)->icon();
476QColor KeyFilterManager::bgColor(
const Key &key)
const
478 return get_color(d->filters, key, &KeyFilter::bgColor);
481QColor KeyFilterManager::fgColor(
const Key &key)
const
483 return get_color(d->filters, key, &KeyFilter::fgColor);
486QColor KeyFilterManager::bgColor(
const UserID &userID)
const
488 return get_color(d->filters, userID, &KeyFilter::bgColor);
491QColor KeyFilterManager::fgColor(
const UserID &userID)
const
493 return get_color(d->filters, userID, &KeyFilter::fgColor);
496QIcon KeyFilterManager::icon(
const Key &key)
const
498 const QString icon = get_string(d->filters, key, &KeyFilter::icon);
502#include "moc_keyfiltermanager.cpp"
static KSharedConfig::Ptr openConfig(const QString &fileName=QString(), OpenFlags mode=FullConfig, QStandardPaths::StandardLocation type=QStandardPaths::GenericConfigLocation)
Default implementation of key filter class.
An abstract base class key filters.
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
const QList< QKeySequence > & reload()
QCoreApplication * instance()
bool isValid() const const
const QAbstractItemModel * model() const const
bool isEmpty() const const
QStringList filter(QStringView str, Qt::CaseSensitivity cs) const const
QFuture< void > filter(QThreadPool *pool, Sequence &sequence, KeepFunctor &&filterFunction)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QVariant fromValue(T &&value)