File indexing completed on 2024-05-12 16:28:06

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