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(
i18n(
"All Certificates"));
72 setId(QStringLiteral(
"all-certificates"));
73 setMatchContexts(Filtering);
80 MyCertificatesKeyFilter()
84 setSpecificity(UINT_MAX - 1);
86 setName(
i18n(
"My Certificates"));
87 setId(QStringLiteral(
"my-certificates"));
88 setMatchContexts(AnyMatchContext);
96 TrustedCertificatesKeyFilter()
100 setValidity(IsAtLeast);
101 setValidityReferenceLevel(UserID::Marginal);
102 setSpecificity(UINT_MAX - 2);
104 setName(
i18n(
"Trusted Certificates"));
105 setId(QStringLiteral(
"trusted-certificates"));
106 setMatchContexts(Filtering);
113 FullCertificatesKeyFilter()
117 setValidity(IsAtLeast);
118 setValidityReferenceLevel(UserID::Full);
119 setSpecificity(UINT_MAX - 3);
121 setName(
i18n(
"Fully Trusted Certificates"));
122 setId(QStringLiteral(
"full-certificates"));
123 setMatchContexts(Filtering);
130 OtherCertificatesKeyFilter()
133 setHasSecret(NotSet);
134 setValidity(IsAtMost);
135 setValidityReferenceLevel(UserID::Never);
136 setSpecificity(UINT_MAX - 4);
138 setName(
i18n(
"Other Certificates"));
139 setId(QStringLiteral(
"other-certificates"));
140 setMatchContexts(Filtering);
149 UncertifiedOpenPGPKeysFilter()
152 setSpecificity(UINT_MAX - 6);
153 setName(
i18n(
"Not Certified Certificates"));
154 setId(QStringLiteral(
"not-certified-certificates"));
156 setMatchContexts(Filtering);
160 bool matches(
const Key &key, MatchContexts contexts)
const override
162 return DefaultKeyFilter::matches(key, contexts) && !Kleo::allUserIDsHaveFullValidity(key);
164 bool matches(
const UserID &userID, MatchContexts contexts)
const override
166 return DefaultKeyFilter::matches(userID.parent(), contexts) && userID.validity() < UserID::Full;
178 setSpecificity(UINT_MAX - 7);
180 setName(
i18n(
"Not Validated Certificates"));
181 setId(QStringLiteral(
"not-validated-certificates"));
182 setMatchContexts(Filtering);
184 bool matches(
const Key &key, MatchContexts contexts)
const override
186 return DefaultKeyFilter::matches(key, contexts) && !Kleo::allUserIDsHaveFullValidity(key);
188 bool matches(
const UserID &userID, MatchContexts contexts)
const override
190 return DefaultKeyFilter::matches(userID.parent(), contexts) && userID.validity() < UserID::Full;
196static std::vector<std::shared_ptr<KeyFilter>> defaultFilters()
198 std::vector<std::shared_ptr<KeyFilter>> result;
200 result.push_back(std::shared_ptr<KeyFilter>(
new MyCertificatesKeyFilter));
201 result.push_back(std::shared_ptr<KeyFilter>(
new TrustedCertificatesKeyFilter));
202 result.push_back(std::shared_ptr<KeyFilter>(
new FullCertificatesKeyFilter));
203 result.push_back(std::shared_ptr<KeyFilter>(
new OtherCertificatesKeyFilter));
204 result.push_back(std::shared_ptr<KeyFilter>(
new AllCertificatesKeyFilter));
205 result.push_back(std::shared_ptr<KeyFilter>(
new UncertifiedOpenPGPKeysFilter));
206 result.push_back(std::shared_ptr<KeyFilter>(
new KeyNotValidFilter));
210class KeyFilterManager::Private
220 model.beginResetModel();
222 model.endResetModel();
225 std::vector<std::shared_ptr<KeyFilter>> filters;
227 GpgME::Protocol protocol = GpgME::UnknownProtocol;
230KeyFilterManager *KeyFilterManager::mSelf =
nullptr;
232KeyFilterManager::KeyFilterManager(
QObject *parent)
244KeyFilterManager::~KeyFilterManager()
252KeyFilterManager *KeyFilterManager::instance()
255 mSelf =
new KeyFilterManager();
260void KeyFilterManager::alwaysFilterByProtocol(GpgME::Protocol protocol)
262 if (protocol != d->protocol) {
263 d->protocol = protocol;
268const std::shared_ptr<KeyFilter> &KeyFilterManager::filterMatching(
const Key &key,
KeyFilter::MatchContexts contexts)
const
270 const auto it = std::find_if(d->filters.cbegin(), d->filters.cend(), [&key, contexts](
const std::shared_ptr<KeyFilter> &filter) {
271 return filter->matches(key, contexts);
273 if (it != d->filters.cend()) {
276 static const std::shared_ptr<KeyFilter> null;
280std::vector<std::shared_ptr<KeyFilter>> KeyFilterManager::filtersMatching(
const Key &key,
KeyFilter::MatchContexts contexts)
const
282 std::vector<std::shared_ptr<KeyFilter>> result;
283 result.reserve(d->filters.size());
284 std::remove_copy_if(d->filters.begin(), d->filters.end(), std::back_inserter(result), [&key, contexts](
const std::shared_ptr<KeyFilter> &filter) {
285 return !filter->matches(key, contexts);
292static const auto byDecreasingSpecificity = [](
const std::shared_ptr<KeyFilter> &lhs,
const std::shared_ptr<KeyFilter> &rhs) {
293 return lhs->specificity() > rhs->specificity();
297void KeyFilterManager::reload()
301 d->filters = defaultFilters();
305 const bool ignoreDeVs = !DeVSCompliance::isCompliant();
308 if (cfg.hasKey(
"is-de-vs") && ignoreDeVs) {
312 d->filters.push_back(std::shared_ptr<KeyFilter>(
new KConfigBasedKeyFilter(cfg)));
314 std::stable_sort(d->filters.begin(), d->filters.end(), byDecreasingSpecificity);
316 if (d->protocol != GpgME::UnknownProtocol) {
318 const auto conflictingValue = (d->protocol == GpgME::OpenPGP) ? DefaultKeyFilter::NotSet :
DefaultKeyFilter::Set;
319 Kleo::erase_if(d->filters, [conflictingValue](
const auto &f) {
320 const auto filter = std::dynamic_pointer_cast<DefaultKeyFilter>(f);
322 return filter->isOpenPGP() == conflictingValue;
325 const auto isOpenPGPValue = (d->protocol == GpgME::OpenPGP) ? DefaultKeyFilter::Set :
DefaultKeyFilter::NotSet;
326 std::for_each(std::begin(d->filters), std::end(d->filters), [isOpenPGPValue](
auto &f) {
327 const auto filter = std::dynamic_pointer_cast<DefaultKeyFilter>(f);
329 return filter->setIsOpenPGP(isOpenPGPValue);
332 qCDebug(LIBKLEO_LOG) <<
"KeyFilterManager::" << __func__ <<
"final filter count is" << d->filters.size();
340const std::shared_ptr<KeyFilter> &KeyFilterManager::keyFilterByID(
const QString &
id)
const
342 const auto it = std::find_if(d->filters.begin(), d->filters.end(), [
id](
const std::shared_ptr<KeyFilter> &filter) {
343 return filter->id() == id;
345 if (it != d->filters.end()) {
348 static const std::shared_ptr<KeyFilter> null;
352const std::shared_ptr<KeyFilter> &KeyFilterManager::fromModelIndex(
const QModelIndex &idx)
const
354 if (!idx.
isValid() || idx.
model() != &d->model || idx.
row() < 0 ||
static_cast<unsigned>(idx.
row()) >= d->filters.size()) {
355 static const std::shared_ptr<KeyFilter> null;
358 return d->filters[idx.
row()];
361QModelIndex KeyFilterManager::toModelIndex(
const std::shared_ptr<KeyFilter> &kf)
const
366 const auto pair = std::equal_range(d->filters.cbegin(), d->filters.cend(), kf, byDecreasingSpecificity);
367 const auto it = std::find(pair.first, pair.second, kf);
368 if (it != pair.second) {
369 return d->model.index(it - d->filters.begin());
377 return m_keyFilterManagerPrivate->filters.size();
382 if (!idx.
isValid() || idx.
model() !=
this || idx.
row() < 0 ||
static_cast<unsigned>(idx.
row()) > m_keyFilterManagerPrivate->filters.size()) {
386 const auto filter = m_keyFilterManagerPrivate->filters[idx.
row()];
396 case KeyFilterManager::FilterIdRole:
399 case KeyFilterManager::FilterMatchContextsRole:
407static KeyFilter::FontDescription
408get_fontdescription(
const std::vector<std::shared_ptr<KeyFilter>> &filters,
const Key &key,
const KeyFilter::FontDescription &initial)
410 return kdtools::accumulate_if(
413 [&key](
const std::shared_ptr<KeyFilter> &filter) {
414 return filter->matches(key, KeyFilter::Appearance);
417 [](
const KeyFilter::FontDescription &lhs,
const std::shared_ptr<KeyFilter> &rhs) {
418 return lhs.resolve(rhs->fontDescription());
422QFont KeyFilterManager::font(
const Key &key,
const QFont &baseFont)
const
424 const KeyFilter::FontDescription fd = get_fontdescription(d->filters, key, KeyFilter::FontDescription());
426 return fd.font(baseFont);
429static QColor get_color(
const std::vector<std::shared_ptr<KeyFilter>> &filters,
const Key &key,
QColor (
KeyFilter::*fun)() const)
431 const auto it = std::find_if(filters.cbegin(), filters.cend(), [&fun, &key](
const std::shared_ptr<KeyFilter> &filter) {
432 return filter->matches(key, KeyFilter::Appearance) && (filter.get()->*fun)().isValid();
434 if (it == filters.cend()) {
437 return (it->get()->*fun)();
441static QColor get_color(
const std::vector<std::shared_ptr<KeyFilter>> &filters,
const UserID &userID,
QColor (
KeyFilter::*fun)() const)
443 const auto it = std::find_if(filters.cbegin(), filters.cend(), [&fun, &userID](
const std::shared_ptr<KeyFilter> &filter) {
444 return filter->matches(userID, KeyFilter::Appearance) && (filter.get()->*fun)().isValid();
446 if (it == filters.cend()) {
449 return (it->get()->*fun)();
453static QString get_string(
const std::vector<std::shared_ptr<KeyFilter>> &filters,
const Key &key,
QString (
KeyFilter::*fun)() const)
455 const auto it = std::find_if(filters.cbegin(), filters.cend(), [&fun, &key](
const std::shared_ptr<KeyFilter> &filter) {
456 return filter->matches(key, KeyFilter::Appearance) && !(filter.get()->*fun)().isEmpty();
458 if (it == filters.cend()) {
461 return (*it)->icon();
465QColor KeyFilterManager::bgColor(
const Key &key)
const
467 return get_color(d->filters, key, &KeyFilter::bgColor);
470QColor KeyFilterManager::fgColor(
const Key &key)
const
472 return get_color(d->filters, key, &KeyFilter::fgColor);
475QColor KeyFilterManager::bgColor(
const UserID &userID)
const
477 return get_color(d->filters, userID, &KeyFilter::bgColor);
480QColor KeyFilterManager::fgColor(
const UserID &userID)
const
482 return get_color(d->filters, userID, &KeyFilter::fgColor);
485QIcon KeyFilterManager::icon(
const Key &key)
const
487 const QString icon = get_string(d->filters, key, &KeyFilter::icon);
491#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 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)