File indexing completed on 2025-01-26 04:57:21

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 "backoffmodemanager.h"
0008 #include "checkphishingurlutil.h"
0009 #include "webengineviewer_debug.h"
0010 
0011 #include <KConfig>
0012 #include <KConfigGroup>
0013 
0014 #include <QTimer>
0015 
0016 using namespace WebEngineViewer;
0017 
0018 Q_GLOBAL_STATIC(BackOffModeManager, s_backOffModeManager)
0019 
0020 class WebEngineViewer::BackOffModeManagerPrivate
0021 {
0022 public:
0023     BackOffModeManagerPrivate(BackOffModeManager *qq)
0024         : q(qq)
0025         , mTimer(new QTimer(q))
0026     {
0027         mTimer->setSingleShot(true);
0028         q->connect(mTimer, &QTimer::timeout, q, &BackOffModeManager::slotTimerFinished);
0029         load();
0030     }
0031 
0032     void save();
0033     void load();
0034     [[nodiscard]] int calculateBackModeTime() const;
0035     void startOffMode();
0036     void exitBackOffMode();
0037     void updateTimer(int seconds);
0038     void slotTimerFinished();
0039 
0040     BackOffModeManager *const q;
0041     QTimer *const mTimer;
0042     int mNumberOfHttpFailed = 0;
0043     bool isInOffMode = false;
0044 };
0045 
0046 void BackOffModeManagerPrivate::save()
0047 {
0048     KConfig phishingurlKConfig(WebEngineViewer::CheckPhishingUrlUtil::configFileName());
0049     KConfigGroup grp = phishingurlKConfig.group(QStringLiteral("BackOffMode"));
0050     grp.writeEntry("Enabled", isInOffMode);
0051     if (isInOffMode) {
0052         const int calculateTimeInSeconds = calculateBackModeTime();
0053         const qint64 delay = QDateTime::currentDateTime().addSecs(calculateTimeInSeconds).toSecsSinceEpoch();
0054         grp.writeEntry("Delay", delay);
0055         updateTimer(calculateTimeInSeconds);
0056     } else {
0057         grp.deleteEntry("Delay");
0058     }
0059     grp.sync();
0060 }
0061 
0062 void BackOffModeManagerPrivate::slotTimerFinished()
0063 {
0064     qCDebug(WEBENGINEVIEWER_LOG) << "Existing from BlackOffMode";
0065     exitBackOffMode();
0066     save();
0067 }
0068 
0069 void BackOffModeManagerPrivate::updateTimer(int seconds)
0070 {
0071     if (mTimer->isActive()) {
0072         mTimer->stop();
0073     }
0074     mTimer->setInterval(seconds * 1000);
0075     mTimer->start();
0076 }
0077 
0078 void BackOffModeManagerPrivate::load()
0079 {
0080     KConfig phishingurlKConfig(WebEngineViewer::CheckPhishingUrlUtil::configFileName());
0081     KConfigGroup grp = phishingurlKConfig.group(QStringLiteral("BackOffMode"));
0082     isInOffMode = grp.readEntry("Enabled", false);
0083     if (isInOffMode) {
0084         const qint64 delay = grp.readEntry("Delay", 0);
0085         const qint64 now = QDateTime::currentDateTimeUtc().toSecsSinceEpoch();
0086         if (delay > now) {
0087             const qint64 diff = (delay - now);
0088             updateTimer(diff);
0089         } else {
0090             // Disable mode.
0091             isInOffMode = false;
0092         }
0093     }
0094 }
0095 
0096 int BackOffModeManagerPrivate::calculateBackModeTime() const
0097 {
0098     return WebEngineViewer::CheckPhishingUrlUtil::generateRandomSecondValue(mNumberOfHttpFailed);
0099 }
0100 
0101 void BackOffModeManagerPrivate::startOffMode()
0102 {
0103     mNumberOfHttpFailed++;
0104     if (isInOffMode) {
0105         qCWarning(WEBENGINEVIEWER_LOG) << "New failed" << mNumberOfHttpFailed;
0106     } else {
0107         qCWarning(WEBENGINEVIEWER_LOG) << "starting back of mode";
0108         isInOffMode = true;
0109     }
0110     save();
0111 }
0112 
0113 void BackOffModeManagerPrivate::exitBackOffMode()
0114 {
0115     isInOffMode = false;
0116     mNumberOfHttpFailed = 0;
0117 }
0118 
0119 BackOffModeManager::BackOffModeManager(QObject *parent)
0120     : QObject(parent)
0121     , d(new BackOffModeManagerPrivate(this))
0122 {
0123 }
0124 
0125 BackOffModeManager::~BackOffModeManager() = default;
0126 
0127 BackOffModeManager *BackOffModeManager::self()
0128 {
0129     return s_backOffModeManager;
0130 }
0131 
0132 bool BackOffModeManager::isInBackOffMode() const
0133 {
0134     return d->isInOffMode;
0135 }
0136 
0137 void BackOffModeManager::startOffMode()
0138 {
0139     d->startOffMode();
0140 }
0141 
0142 int BackOffModeManager::numberOfHttpFailed() const
0143 {
0144     return d->mNumberOfHttpFailed;
0145 }
0146 
0147 void BackOffModeManager::slotTimerFinished()
0148 {
0149     d->slotTimerFinished();
0150 }