File indexing completed on 2025-02-23 05:00:17

0001 /*
0002    SPDX-FileCopyrightText: 2016-2024 Laurent Montel <montel@kde.org>
0003 
0004    SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "checkphishingurlcache.h"
0008 #include "checkphishingurlutil.h"
0009 #include "webengineviewer_debug.h"
0010 #include <KConfig>
0011 #include <KConfigGroup>
0012 #include <QMap>
0013 
0014 using namespace WebEngineViewer;
0015 
0016 struct UrlCacheInfo {
0017     UrlCacheInfo() = default;
0018 
0019     [[nodiscard]] bool isMalWare() const;
0020     [[nodiscard]] bool isValid() const;
0021     CheckPhishingUrlCache::UrlStatus status = CheckPhishingUrlCache::Unknown;
0022     uint verifyCacheAfterThisTime = 0;
0023 };
0024 
0025 bool UrlCacheInfo::isMalWare() const
0026 {
0027     return status == CheckPhishingUrlCache::MalWare;
0028 }
0029 
0030 bool UrlCacheInfo::isValid() const
0031 {
0032     return status != CheckPhishingUrlCache::Unknown;
0033 }
0034 
0035 class WebEngineViewer::CheckPhishingUrlCachePrivate
0036 {
0037 public:
0038     CheckPhishingUrlCachePrivate()
0039     {
0040         load();
0041     }
0042 
0043     CheckPhishingUrlCache::UrlStatus urlStatus(const QUrl &url);
0044     void addCheckPhishingUrlResult(const QUrl &url, bool correctUrl, uint verifyCacheAfterThisTime);
0045     void clearCache();
0046     void load();
0047     void save();
0048 
0049 private:
0050     QMap<QUrl, UrlCacheInfo> mCacheCheckedUrl;
0051 };
0052 
0053 void CheckPhishingUrlCachePrivate::clearCache()
0054 {
0055     mCacheCheckedUrl.clear();
0056     save();
0057 }
0058 
0059 void CheckPhishingUrlCachePrivate::load()
0060 {
0061     mCacheCheckedUrl.clear();
0062     KConfig phishingurlKConfig(WebEngineViewer::CheckPhishingUrlUtil::configFileName());
0063     KConfigGroup grp = phishingurlKConfig.group(QStringLiteral("MalwareUrl"));
0064     const QList<QUrl> listMalware = grp.readEntry("Url", QList<QUrl>());
0065     const QList<double> listMalwareCachedTime = grp.readEntry("CachedTime", QList<double>());
0066     if (listMalware.count() != listMalwareCachedTime.count()) {
0067         qCWarning(WEBENGINEVIEWER_LOG) << "CheckPhishingUrlCachePrivate invalid number of data stored";
0068     } else {
0069         UrlCacheInfo info;
0070         const int numberOfMalware = listMalware.count();
0071         for (int i = 0; i < numberOfMalware; ++i) {
0072             info.status = WebEngineViewer::CheckPhishingUrlCache::MalWare;
0073             info.verifyCacheAfterThisTime = listMalwareCachedTime.at(i);
0074             if (WebEngineViewer::CheckPhishingUrlUtil::cachedValueStillValid(info.verifyCacheAfterThisTime)) {
0075                 mCacheCheckedUrl.insert(listMalware.at(i), info);
0076             }
0077         }
0078     }
0079 }
0080 
0081 void CheckPhishingUrlCachePrivate::save()
0082 {
0083     KConfig phishingurlKConfig(WebEngineViewer::CheckPhishingUrlUtil::configFileName());
0084     KConfigGroup grp = phishingurlKConfig.group(QStringLiteral("MalwareUrl"));
0085 
0086     QList<QUrl> listMalware;
0087     QList<double> listMalwareCachedTime;
0088 
0089     QMap<QUrl, UrlCacheInfo>::const_iterator i = mCacheCheckedUrl.constBegin();
0090     const QMap<QUrl, UrlCacheInfo>::const_iterator end = mCacheCheckedUrl.constEnd();
0091     while (i != end) {
0092         const UrlCacheInfo info = i.value();
0093         if (info.isMalWare() && WebEngineViewer::CheckPhishingUrlUtil::cachedValueStillValid(info.verifyCacheAfterThisTime)) {
0094             listMalware.append(i.key());
0095             listMalwareCachedTime.append(info.verifyCacheAfterThisTime);
0096         }
0097         ++i;
0098     }
0099     grp.writeEntry("Url", listMalware);
0100     grp.writeEntry("CachedTime", listMalwareCachedTime);
0101     grp.sync();
0102 }
0103 
0104 CheckPhishingUrlCache::UrlStatus CheckPhishingUrlCachePrivate::urlStatus(const QUrl &url)
0105 {
0106     const UrlCacheInfo info = mCacheCheckedUrl.value(url, UrlCacheInfo());
0107     if (info.isValid()) {
0108         if (info.verifyCacheAfterThisTime > 0) {
0109             if (CheckPhishingUrlUtil::cachedValueStillValid(info.verifyCacheAfterThisTime)) {
0110                 return info.status;
0111             } else {
0112                 return CheckPhishingUrlCache::Unknown;
0113             }
0114         } else {
0115             return info.status;
0116         }
0117     } else {
0118         return CheckPhishingUrlCache::Unknown;
0119     }
0120 }
0121 
0122 void CheckPhishingUrlCachePrivate::addCheckPhishingUrlResult(const QUrl &url, bool correctUrl, uint verifyCacheAfterThisTime)
0123 {
0124     UrlCacheInfo info;
0125     info.status = correctUrl ? CheckPhishingUrlCache::UrlOk : CheckPhishingUrlCache::MalWare;
0126     info.verifyCacheAfterThisTime = correctUrl ? 0 : verifyCacheAfterThisTime;
0127     mCacheCheckedUrl.insert(url, info);
0128     if (info.status == CheckPhishingUrlCache::MalWare) {
0129         save();
0130     }
0131 }
0132 
0133 CheckPhishingUrlCache::CheckPhishingUrlCache(QObject *parent)
0134     : QObject(parent)
0135     , d(new CheckPhishingUrlCachePrivate)
0136 {
0137 }
0138 
0139 CheckPhishingUrlCache::~CheckPhishingUrlCache() = default;
0140 
0141 void CheckPhishingUrlCache::addCheckingUrlResult(const QUrl &url, bool correctUrl, uint verifyCacheAfterThisTime)
0142 {
0143     d->addCheckPhishingUrlResult(url, correctUrl, verifyCacheAfterThisTime);
0144 }
0145 
0146 CheckPhishingUrlCache::UrlStatus CheckPhishingUrlCache::urlStatus(const QUrl &url)
0147 {
0148     return d->urlStatus(url);
0149 }
0150 
0151 void CheckPhishingUrlCache::clearCache()
0152 {
0153     d->clearCache();
0154 }
0155 
0156 CheckPhishingUrlCache *CheckPhishingUrlCache::self()
0157 {
0158     static CheckPhishingUrlCache s_self;
0159     return &s_self;
0160 }
0161 
0162 #include "moc_checkphishingurlcache.cpp"