File indexing completed on 2024-05-12 05:04:11

0001 // SPDX-FileCopyrightText: 2023 Rishi Kumar <rsi.dev17@gmail.com>
0002 // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0003 
0004 #include "federationtoolmodel.h"
0005 
0006 #include "abstractaccount.h"
0007 #include "accountmanager.h"
0008 
0009 #include <KLocalizedString>
0010 
0011 using namespace Qt::Literals::StringLiterals;
0012 
0013 FederationToolModel::FederationToolModel(QObject *parent)
0014     : QAbstractListModel(parent)
0015 {
0016     filltimeline();
0017 }
0018 
0019 QVariant FederationToolModel::data(const QModelIndex &index, int role) const
0020 {
0021     Q_ASSERT(checkIndex(index, QAbstractItemModel::CheckIndexOption::IndexIsValid));
0022 
0023     const auto &federationInfo = m_federations[index.row()];
0024     switch (role) {
0025     case IdRole:
0026         return federationInfo.id();
0027     case DomainRole:
0028         return federationInfo.domain();
0029     case CreatedAtRole:
0030         return federationInfo.createdAt();
0031     case SeverityRole:
0032         return federationInfo.severity();
0033     case RejectMediaRole:
0034         return federationInfo.rejectMedia();
0035     case RejectReportsRole:
0036         return federationInfo.rejectReports();
0037     case PrivateCommentRole:
0038         return federationInfo.privateComment();
0039     case PublicCommentRole:
0040         return federationInfo.publicComment();
0041     case ObfuscateRole:
0042         return federationInfo.obfuscate();
0043     default:
0044         return {};
0045     }
0046 }
0047 
0048 int FederationToolModel::rowCount(const QModelIndex &parent) const
0049 {
0050     return parent.isValid() ? 0 : m_federations.count();
0051 }
0052 
0053 QHash<int, QByteArray> FederationToolModel::roleNames() const
0054 {
0055     return {
0056         {IdRole, "id"},
0057         {DomainRole, "domain"},
0058         {CreatedAtRole, "createdAt"},
0059         {SeverityRole, "severity"},
0060         {RejectMediaRole, "rejectMedia"},
0061         {RejectReportsRole, "rejectReports"},
0062         {PrivateCommentRole, "privateComment"},
0063         {PublicCommentRole, "publicComment"},
0064         {ObfuscateRole, "obfuscate"},
0065     };
0066 }
0067 
0068 bool FederationToolModel::loading() const
0069 {
0070     return m_loading;
0071 }
0072 
0073 void FederationToolModel::setLoading(bool loading)
0074 {
0075     if (m_loading == loading) {
0076         return;
0077     }
0078     m_loading = loading;
0079     Q_EMIT loadingChanged();
0080 }
0081 
0082 FederationToolModel::FederationAction FederationToolModel::federationAction() const
0083 {
0084     return m_federationAction;
0085 }
0086 
0087 void FederationToolModel::setFederationAction(const FederationAction &federationAction)
0088 {
0089     if (m_federationAction == federationAction) {
0090         return;
0091     }
0092     m_federationAction = federationAction;
0093     Q_EMIT federationActionChanged();
0094     clear();
0095     filltimeline(m_federationAction);
0096 }
0097 
0098 void FederationToolModel::removeDomainBlock(const int row)
0099 {
0100     auto account = AccountManager::instance().selectedAccount();
0101     const auto &federationInfo = m_federations[row];
0102     const auto federationId = federationInfo.id();
0103 
0104     account->deleteResource(account->apiUrl(QStringLiteral("/api/v1/admin/domain_blocks/%1").arg(federationId)), true, this, [=](QNetworkReply *reply) {
0105         const auto doc = QJsonDocument::fromJson(reply->readAll()).object();
0106         beginRemoveRows({}, row, row);
0107         m_federations.removeAt(row);
0108         endRemoveRows();
0109         Q_EMIT dataChanged(index(row, 0), index(row, 0));
0110     });
0111 }
0112 
0113 void FederationToolModel::removeAllowedDomain(const int row)
0114 {
0115     auto account = AccountManager::instance().selectedAccount();
0116     const auto &federationInfo = m_federations[row];
0117     const auto federationId = federationInfo.id();
0118 
0119     account->deleteResource(account->apiUrl(QStringLiteral("/api/v1/admin/domain_allows/%1").arg(federationId)), true, this, [=](QNetworkReply *reply) {
0120         const auto doc = QJsonDocument::fromJson(reply->readAll()).object();
0121         beginRemoveRows({}, row, row);
0122         m_federations.removeAt(row);
0123         endRemoveRows();
0124         Q_EMIT dataChanged(index(row, 0), index(row, 0));
0125     });
0126 }
0127 
0128 void FederationToolModel::updateDomainBlock(const int row,
0129                                             const QString &severity,
0130                                             const QString &publicComment,
0131                                             const QString &privateComment,
0132                                             const bool &rejectMedia,
0133                                             const bool &rejectReports,
0134                                             const bool &obfuscateReport)
0135 {
0136     QJsonObject obj{
0137         {QStringLiteral("severity"), severity},
0138         {QStringLiteral("public_comment"), publicComment},
0139         {QStringLiteral("private_comment"), privateComment},
0140         {QStringLiteral("reject_reports"), rejectReports},
0141         {QStringLiteral("reject_media"), rejectMedia},
0142         {QStringLiteral("obfuscate"), obfuscateReport},
0143     };
0144 
0145     const auto doc = QJsonDocument(obj);
0146 
0147     const auto account = AccountManager::instance().selectedAccount();
0148     auto &federationInfo = m_federations[row];
0149     const auto federationId = federationInfo.id();
0150 
0151     account->put(account->apiUrl(QStringLiteral("/api/v1/admin/domain_blocks/%1").arg(federationId)),
0152                  doc,
0153                  true,
0154                  this,
0155                  [=, &federationInfo](QNetworkReply *reply) {
0156                      const auto doc = QJsonDocument::fromJson(reply->readAll());
0157                      const auto jsonObj = doc.object();
0158 
0159                      if (!jsonObj.value("error"_L1).isUndefined()) {
0160                          account->errorOccured(i18n("Error occured when making a PUT request to update the domain block."));
0161                      }
0162                      federationInfo.setPublicComment(publicComment);
0163                      federationInfo.setPrivateComment(privateComment);
0164                      federationInfo.setRejectMedia(rejectMedia);
0165                      federationInfo.setRejectReports(rejectReports);
0166                      federationInfo.setObfuscate(obfuscateReport);
0167                      federationInfo.setSeverity(severity);
0168                      Q_EMIT dataChanged(index(row, 0), index(row, 0));
0169                  });
0170 }
0171 
0172 void FederationToolModel::newDomainBlock(const QString &domain,
0173                                          const QString &severity,
0174                                          const QString &publicComment,
0175                                          const QString &privateComment,
0176                                          const bool &rejectMedia,
0177                                          const bool &rejectReports,
0178                                          const bool &obfuscateReport)
0179 {
0180     QJsonObject obj{
0181         {QStringLiteral("severity"), severity},
0182         {QStringLiteral("domain"), domain},
0183         {QStringLiteral("public_comment"), publicComment},
0184         {QStringLiteral("private_comment"), privateComment},
0185         {QStringLiteral("reject_reports"), rejectReports},
0186         {QStringLiteral("reject_media"), rejectMedia},
0187         {QStringLiteral("obfuscate"), obfuscateReport},
0188     };
0189 
0190     const auto doc = QJsonDocument(obj);
0191 
0192     const auto account = AccountManager::instance().selectedAccount();
0193 
0194     const QUrl url = account->apiUrl(QStringLiteral("/api/v1/admin/domain_blocks"));
0195 
0196     account->post(url, doc, true, this, [=](QNetworkReply *reply) {
0197         auto doc = QJsonDocument::fromJson(reply->readAll());
0198         auto jsonObj = doc.object();
0199         auto newFederation = FederationInfo::fromSourceData(jsonObj);
0200 
0201         beginInsertRows({}, m_federations.size(), m_federations.size());
0202         m_federations += newFederation;
0203         endInsertRows();
0204     });
0205 }
0206 
0207 void FederationToolModel::newDomainAllow(const QString &domain)
0208 {
0209     QJsonObject obj{
0210         {QStringLiteral("domain"), domain},
0211     };
0212 
0213     const auto doc = QJsonDocument(obj);
0214 
0215     const auto account = AccountManager::instance().selectedAccount();
0216 
0217     const QUrl url = account->apiUrl(QStringLiteral("/api/v1/admin/domain_allows"));
0218 
0219     account->post(url, doc, true, this, [=](QNetworkReply *reply) {
0220         auto doc = QJsonDocument::fromJson(reply->readAll());
0221         auto jsonObj = doc.object();
0222         auto newFederation = FederationInfo::fromSourceData(jsonObj);
0223 
0224         beginInsertRows({}, m_federations.size(), m_federations.size());
0225         m_federations += newFederation;
0226         endInsertRows();
0227     });
0228 }
0229 
0230 void FederationToolModel::clear()
0231 {
0232     beginResetModel();
0233     m_federations.clear();
0234     m_next.clear();
0235     endResetModel();
0236     setLoading(false);
0237 }
0238 
0239 void FederationToolModel::filltimeline(FederationAction action)
0240 {
0241     const auto account = AccountManager::instance().selectedAccount();
0242 
0243     if (m_loading) {
0244         return;
0245     }
0246     setLoading(true);
0247     QUrl url;
0248     if (m_next.isEmpty()) {
0249         switch (action) {
0250         case FederationAction::AllowedDomains:
0251             url = account->apiUrl(QStringLiteral("/api/v1/admin/domain_allows"));
0252             break;
0253         case FederationAction::BlockedDomains:
0254             url = account->apiUrl(QStringLiteral("/api/v1/admin/domain_blocks"));
0255             break;
0256         }
0257     } else {
0258         url = m_next;
0259     }
0260 
0261     account->get(url, true, this, [this](QNetworkReply *reply) {
0262         const auto doc = QJsonDocument::fromJson(reply->readAll());
0263         const auto federations = doc.array();
0264 
0265         if (!federations.isEmpty()) {
0266             static QRegularExpression re(QStringLiteral("<(.*)>; rel=\"next\""));
0267             const auto next = reply->rawHeader(QByteArrayLiteral("Link"));
0268             const auto match = re.match(QString::fromUtf8(next));
0269             if (re.isValid()) {
0270                 m_next = QUrl::fromUserInput(match.captured(1));
0271             }
0272             QList<FederationInfo> fetchedFederations;
0273 
0274             std::transform(
0275                 federations.cbegin(),
0276                 federations.cend(),
0277                 std::back_inserter(fetchedFederations),
0278                 [=](const QJsonValue &value) -> auto{ return FederationInfo::fromSourceData(value.toObject()); });
0279             beginInsertRows({}, m_federations.size(), m_federations.size() + fetchedFederations.size() - 1);
0280             m_federations += fetchedFederations;
0281             endInsertRows();
0282         }
0283         setLoading(false);
0284     });
0285 }
0286 
0287 #include "moc_federationtoolmodel.cpp"