7#include "createphishingurldatabasejob.h"
8#include "checkphishingurlutil.h"
9#include "updatedatabaseinfo.h"
10#include "webengineviewer_debug.h"
11#include <PimCommon/NetworkManager>
13#include <QJsonDocument>
16using namespace WebEngineViewer;
18WEBENGINEVIEWER_EXPORT
bool webengineview_useCompactJson_CreatePhishingUrlDataBaseJob =
true;
20class WebEngineViewer::CreatePhishingUrlDataBaseJobPrivate
23 [[nodiscard]] UpdateDataBaseInfo::CompressionType parseCompressionType(
const QString &str);
25 [[nodiscard]]
QList<Removal> parseRemovals(
const QVariantList &lst);
28 CreatePhishingUrlDataBaseJob::ContraintsCompressionType mContraintsCompressionType = CreatePhishingUrlDataBaseJob::RawCompression;
29 CreatePhishingUrlDataBaseJob::DataBaseDownloadType mDataBaseDownloadNeeded = CreatePhishingUrlDataBaseJob::FullDataBase;
33CreatePhishingUrlDataBaseJob::CreatePhishingUrlDataBaseJob(
QObject *parent)
35 , d(new CreatePhishingUrlDataBaseJobPrivate)
39 d->mNetworkAccessManager->setStrictTransportSecurityEnabled(
true);
40 d->mNetworkAccessManager->enableStrictTransportSecurityStore(
true);
43 connect(d->mNetworkAccessManager, &QNetworkAccessManager::sslErrors,
this, &CreatePhishingUrlDataBaseJob::slotSslErrors);
46CreatePhishingUrlDataBaseJob::~CreatePhishingUrlDataBaseJob() =
default;
50 qCDebug(WEBENGINEVIEWER_LOG) <<
" void CreatePhishingUrlDataBaseJob::slotSslErrors(QNetworkReply *reply, const QList<QSslError> &error)" <<
error.count();
54void CreatePhishingUrlDataBaseJob::start()
56 if (!PimCommon::NetworkManager::self()->isOnline()) {
57 Q_EMIT finished(UpdateDataBaseInfo(), BrokenNetwork);
61 query.addQueryItem(QStringLiteral(
"key"), WebEngineViewer::CheckPhishingUrlUtil::apiKey());
62 QUrl safeUrl =
QUrl(QStringLiteral(
"https://safebrowsing.googleapis.com/v4/threatListUpdates:fetch"));
69 Q_EMIT debugJson(baPostData);
70 qCDebug(WEBENGINEVIEWER_LOG) <<
" postData.toJson()" << baPostData;
74 QNetworkReply *reply = d->mNetworkAccessManager->post(request, baPostData);
79void CreatePhishingUrlDataBaseJob::setDataBaseState(
const QString &value)
81 d->mDataBaseState = value;
87 qWarning() <<
" error " <<
error <<
" error string : " << reply->
errorString();
92QByteArray CreatePhishingUrlDataBaseJob::jsonRequest()
const
97 "clientId" :
"yourcompanyname",
98 "clientVersion" :
"1.5.2"
100 "listUpdateRequests" : [{
101 "threatType" :
"MALWARE",
102 "platformType" :
"WINDOWS",
103 "threatEntryType" :
"URL",
104 "state" :
"Gg4IBBADIgYQgBAiAQEoAQ==",
106 "maxUpdateEntries" : 2048,
107 "maxDatabaseEntries" : 4096,
109 "supportedCompressions" : [
"RAW"]
114 QVariantMap clientMap;
117 clientMap.insert(QStringLiteral(
"clientId"), QStringLiteral(
"KDE"));
118 clientMap.insert(QStringLiteral(
"clientVersion"), CheckPhishingUrlUtil::versionApps());
119 map.insert(QStringLiteral(
"client"), clientMap);
121 QVariantList listUpdateRequests;
123 QVariantMap threatMap;
124 threatMap.insert(QStringLiteral(
"platformType"), QStringLiteral(
"WINDOWS"));
125 threatMap.insert(QStringLiteral(
"threatType"), QStringLiteral(
"MALWARE"));
126 threatMap.insert(QStringLiteral(
"threatEntryType"), QStringLiteral(
"URL"));
129 QVariantMap contraintsMap;
130 QVariantList contraintsCompressionList;
132 switch (d->mContraintsCompressionType) {
133 case RiceCompression:
134 compressionStr = QStringLiteral(
"RICE");
137 compressionStr = QStringLiteral(
"RAW");
140 contraintsCompressionList.
append(compressionStr);
141 contraintsMap.insert(QStringLiteral(
"supportedCompressions"), contraintsCompressionList);
142 threatMap.insert(QStringLiteral(
"constraints"), contraintsMap);
145 switch (d->mDataBaseDownloadNeeded) {
147 qCDebug(WEBENGINEVIEWER_LOG) <<
" full update";
148 threatMap.insert(QStringLiteral(
"state"),
QString());
151 qCDebug(WEBENGINEVIEWER_LOG) <<
" update database";
152 if (d->mDataBaseState.isEmpty()) {
153 qCWarning(WEBENGINEVIEWER_LOG) <<
"Partial Download asked but database set is empty";
155 threatMap.insert(QStringLiteral(
"state"), d->mDataBaseState);
159 listUpdateRequests.append(threatMap);
161 map.insert(QStringLiteral(
"listUpdateRequests"), listUpdateRequests);
168void CreatePhishingUrlDataBaseJob::setDataBaseDownloadNeeded(CreatePhishingUrlDataBaseJob::DataBaseDownloadType type)
170 d->mDataBaseDownloadNeeded = type;
173void CreatePhishingUrlDataBaseJob::slotDownloadDataBaseFinished(
QNetworkReply *reply)
176 Q_EMIT debugJsonResult(returnValue);
177 parseResult(returnValue);
181RiceDeltaEncoding CreatePhishingUrlDataBaseJobPrivate::parseRiceDeltaEncoding(
const QMap<QString, QVariant> &map)
183 RiceDeltaEncoding riceDeltaEncodingTmp;
186 for (; riceHashesIt != riceHashesItEnd; ++riceHashesIt) {
187 const QString key = riceHashesIt.key();
189 riceDeltaEncodingTmp.firstValue = riceHashesIt.value().toByteArray();
191 riceDeltaEncodingTmp.riceParameter = riceHashesIt.value().toInt();
193 riceDeltaEncodingTmp.numberEntries = riceHashesIt.value().toInt();
195 riceDeltaEncodingTmp.encodingData = riceHashesIt.value().toByteArray();
197 qCDebug(WEBENGINEVIEWER_LOG) <<
" CreatePhishingUrlDataBaseJob::parseRiceDeltaEncoding unknown riceDeltaEncoding key " << key;
200 return riceDeltaEncodingTmp;
203QList<Addition> CreatePhishingUrlDataBaseJobPrivate::parseAdditions(
const QVariantList &lst)
207 if (v.canConvert<QVariantMap>()) {
210 while (mapIt.hasNext()) {
212 const QString keyStr = mapIt.key();
214 tmp.compressionType = parseCompressionType(mapIt.value().toString());
216 RiceDeltaEncoding riceDeltaEncodingTmp = parseRiceDeltaEncoding(mapIt.value().toMap());
217 if (riceDeltaEncodingTmp.isValid()) {
218 tmp.riceDeltaEncoding = riceDeltaEncodingTmp;
222 while (rawHashesIt.hasNext()) {
224 const QString key = rawHashesIt.key();
228 tmp.prefixSize = rawHashesIt.value().toInt();
230 qCDebug(WEBENGINEVIEWER_LOG) <<
" CreatePhishingUrlDataBaseJob::parseAdditions unknown rawHashes key " << key;
234 qCDebug(WEBENGINEVIEWER_LOG) <<
" CreatePhishingUrlDataBaseJob::parseAdditions unknown mapIt.key() " << keyStr;
241 qCDebug(WEBENGINEVIEWER_LOG) <<
" CreatePhishingUrlDataBaseJob::parseAdditions not parsing type " << v.typeName();
247UpdateDataBaseInfo::CompressionType CreatePhishingUrlDataBaseJobPrivate::parseCompressionType(
const QString &str)
249 UpdateDataBaseInfo::CompressionType type(UpdateDataBaseInfo::UnknownCompression);
251 type = UpdateDataBaseInfo::UnknownCompression;
253 type = UpdateDataBaseInfo::RiceCompression;
255 type = UpdateDataBaseInfo::RawCompression;
257 qCWarning(WEBENGINEVIEWER_LOG) <<
"CreatePhishingUrlDataBaseJob::parseCompressionType unknown compression type " << str;
262QList<Removal> CreatePhishingUrlDataBaseJobPrivate::parseRemovals(
const QVariantList &lst)
266 if (v.canConvert<QVariantMap>()) {
269 while (mapIt.hasNext()) {
271 const QString keyStr = mapIt.key();
273 tmp.compressionType = parseCompressionType(mapIt.value().toString());
275 RiceDeltaEncoding riceDeltaEncodingTmp = parseRiceDeltaEncoding(mapIt.value().toMap());
276 if (riceDeltaEncodingTmp.isValid()) {
277 tmp.riceDeltaEncoding = riceDeltaEncodingTmp;
280 const QVariantMap
map = mapIt.value().toMap();
282 while (rawIndicesIt.hasNext()) {
285 const QVariantList rawList = rawIndicesIt.value().toList();
287 indexList.
reserve(rawList.count());
288 for (
const QVariant &var : rawList) {
289 indexList.
append(var.toUInt());
291 tmp.indexes = indexList;
293 qCDebug(WEBENGINEVIEWER_LOG) <<
"rawIndicesIt.key() unknown " << rawIndicesIt.key();
297 qCDebug(WEBENGINEVIEWER_LOG) <<
" CreatePhishingUrlDataBaseJob::parseRemovals unknown mapIt.key() " << keyStr;
304 qCDebug(WEBENGINEVIEWER_LOG) <<
" CreatePhishingUrlDataBaseJob::parseRemovals not parsing type " << v.typeName();
310void CreatePhishingUrlDataBaseJob::parseResult(
const QByteArray &value)
312 UpdateDataBaseInfo databaseInfo;
315 Q_EMIT finished(databaseInfo, InvalidData);
318 if (answer.isEmpty()) {
319 Q_EMIT finished(databaseInfo, InvalidData);
322 while (i.hasNext()) {
325 const QVariantList info = i.value().toList();
326 if (info.count() == 1) {
327 const QVariant infoVar = info.at(0);
330 while (mapIt.hasNext()) {
332 const QString mapKey = mapIt.key();
334 const QVariantList lst = mapIt.value().toList();
337 databaseInfo.additionList.
append(addList);
340 const QVariantList lst = mapIt.value().toList();
343 databaseInfo.removalList.
append(removeList);
347 while (mapCheckSum.hasNext()) {
350 databaseInfo.sha256 = mapCheckSum.value().toByteArray();
352 qCDebug(WEBENGINEVIEWER_LOG) <<
"Invalid checksum key" << mapCheckSum.key();
356 databaseInfo.newClientState = mapIt.value().toString();
358 databaseInfo.platformType = mapIt.value().toString();
360 const QString str = mapIt.value().toString();
362 databaseInfo.responseType = UpdateDataBaseInfo::FullUpdate;
364 databaseInfo.responseType = UpdateDataBaseInfo::PartialUpdate;
366 qCDebug(WEBENGINEVIEWER_LOG) <<
" unknown responsetype " << str;
367 databaseInfo.responseType = UpdateDataBaseInfo::Unknown;
370 databaseInfo.threatEntryType = mapIt.value().toString();
372 databaseInfo.threatType = mapIt.value().toString();
374 qCDebug(WEBENGINEVIEWER_LOG) <<
" unknown key " << mapKey;
380 databaseInfo.minimumWaitDuration = i.value().toString();
382 qCDebug(WEBENGINEVIEWER_LOG) <<
" map key unknown " << i.key();
385 Q_EMIT finished(databaseInfo, ValidData);
391void CreatePhishingUrlDataBaseJob::setContraintsCompressionType(CreatePhishingUrlDataBaseJob::ContraintsCompressionType type)
393 d->mContraintsCompressionType = type;
396#include "moc_createphishingurldatabasejob.cpp"
std::optional< QSqlQuery > query(const QString &queryStatement)
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
QByteArray fromBase64(const QByteArray &base64, Base64Options options)
QString errorString() const const
QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error)
QJsonDocument fromVariant(const QVariant &variant)
bool isNull() const const
QByteArray toJson(JsonFormat format) const const
QVariant toVariant() const const
void append(QList< T > &&value)
bool isEmpty() const const
void reserve(qsizetype size)
void finished(QNetworkReply *reply)
void errorOccurred(QNetworkReply::NetworkError code)
virtual void ignoreSslErrors()
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
T qobject_cast(QObject *object)
QObject * sender() const const
QString & append(QChar ch)
QFuture< void > map(Iterator begin, Iterator end, MapFunctor &&function)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
void setQuery(const QString &query, ParsingMode mode)
bool canConvert() const const
QMap< QString, QVariant > toMap() const const