/* * Copyright (C) by Camila Ayres * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. */ #include "remotewipe.h" #include "folderman.h" #include #include #include #include namespace OCC { Q_LOGGING_CATEGORY(lcRemoteWipe, "nextcloud.gui.remotewipe", QtInfoMsg) RemoteWipe::RemoteWipe(AccountPtr account, QObject *parent) : QObject(parent), _account(account), _appPassword(QString()), _accountRemoved(false), _networkManager(nullptr), _networkReplyCheck(nullptr), _networkReplySuccess(nullptr) { QObject::connect(AccountManager::instance(), &AccountManager::accountRemoved, this, [=](AccountState *) { _accountRemoved = true; }); QObject::connect(this, &RemoteWipe::authorized, FolderMan::instance(), &FolderMan::slotWipeFolderForAccount); QObject::connect(FolderMan::instance(), &FolderMan::wipeDone, this, &RemoteWipe::notifyServerSuccessJob); QObject::connect(_account.data(), &Account::appPasswordRetrieved, this, &RemoteWipe::startCheckJobWithAppPassword); } void RemoteWipe::startCheckJobWithAppPassword(QString pwd){ if(pwd.isEmpty()) return; _appPassword = pwd; QUrl requestUrl = Utility::concatUrlPath(_account->url().toString(), QLatin1String("/index.php/core/wipe/check")); QNetworkRequest request; request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); request.setUrl(requestUrl); request.setSslConfiguration(_account->getOrCreateSslConfig()); auto requestBody = new QBuffer; QUrlQuery arguments(QString("token=%1").arg(_appPassword)); requestBody->setData(arguments.query(QUrl::FullyEncoded).toLatin1()); _networkReplyCheck = _networkManager.post(request, requestBody); QObject::connect(&_networkManager, SIGNAL(sslErrors(QNetworkReply *, QList)), _account.data(), SLOT(slotHandleSslErrors(QNetworkReply *, QList))); QObject::connect(_networkReplyCheck, &QNetworkReply::finished, this, &RemoteWipe::checkJobSlot); } void RemoteWipe::checkJobSlot() { auto jsonData = _networkReplyCheck->readAll(); QJsonParseError jsonParseError; QJsonObject json = QJsonDocument::fromJson(jsonData, &jsonParseError).object(); bool wipe = false; //check for errors if (_networkReplyCheck->error() != QNetworkReply::NoError || jsonParseError.error != QJsonParseError::NoError) { QString errorReason; QString errorFromJson = json["error"].toString(); if (!errorFromJson.isEmpty()) { qCWarning(lcRemoteWipe) << QString("Error returned from the server: %1") .arg(errorFromJson.toHtmlEscaped()); } else if (_networkReplyCheck->error() != QNetworkReply::NoError) { qCWarning(lcRemoteWipe) << QString("There was an error accessing the 'token' endpoint:
%1") .arg(_networkReplyCheck->errorString().toHtmlEscaped()); } else if (jsonParseError.error != QJsonParseError::NoError) { qCWarning(lcRemoteWipe) << QString("Could not parse the JSON returned from the server:
%1") .arg(jsonParseError.errorString()); } else { qCWarning(lcRemoteWipe) << QString("The reply from the server did not contain all expected fields"); } // check for wipe request } else if(!json.value("wipe").isUndefined()){ wipe = json["wipe"].toBool(); } auto manager = AccountManager::instance(); auto accountState = manager->account(_account->displayName()).data(); if(wipe){ /* IMPORTANT - remove later - FIXME MS@2019-12-07 --> * TODO: For "Log out" & "Remove account": Remove client CA certs and KEY! * * Disabled as long as selecting another cert is not supported by the UI. * * Being able to specify a new certificate is important anyway: expiry etc. * * We introduce this dirty hack here, to allow deleting them upon Remote Wipe. */ _account->setRemoteWipeRequested_HACK(); // <-- FIXME MS@2019-12-07 // delete account manager->deleteAccount(accountState); manager->save(); // delete data emit authorized(accountState); } else { // ask user for his credentials again accountState->handleInvalidCredentials(); } _networkReplyCheck->deleteLater(); } void RemoteWipe::notifyServerSuccessJob(AccountState *accountState, bool dataWiped){ if(_accountRemoved && dataWiped && _account == accountState->account()){ QUrl requestUrl = Utility::concatUrlPath(_account->url().toString(), QLatin1String("/index.php/core/wipe/success")); QNetworkRequest request; request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); request.setUrl(requestUrl); request.setSslConfiguration(_account->getOrCreateSslConfig()); auto requestBody = new QBuffer; QUrlQuery arguments(QString("token=%1").arg(_appPassword)); requestBody->setData(arguments.query(QUrl::FullyEncoded).toLatin1()); _networkReplySuccess = _networkManager.post(request, requestBody); QObject::connect(_networkReplySuccess, &QNetworkReply::finished, this, &RemoteWipe::notifyServerSuccessJobSlot); } } void RemoteWipe::notifyServerSuccessJobSlot() { auto jsonData = _networkReplySuccess->readAll(); QJsonParseError jsonParseError; QJsonObject json = QJsonDocument::fromJson(jsonData, &jsonParseError).object(); if (_networkReplySuccess->error() != QNetworkReply::NoError || jsonParseError.error != QJsonParseError::NoError) { QString errorReason; QString errorFromJson = json["error"].toString(); if (!errorFromJson.isEmpty()) { qCWarning(lcRemoteWipe) << QString("Error returned from the server: %1") .arg(errorFromJson.toHtmlEscaped()); } else if (_networkReplySuccess->error() != QNetworkReply::NoError) { qCWarning(lcRemoteWipe) << QString("There was an error accessing the 'success' endpoint:
%1") .arg(_networkReplySuccess->errorString().toHtmlEscaped()); } else if (jsonParseError.error != QJsonParseError::NoError) { qCWarning(lcRemoteWipe) << QString("Could not parse the JSON returned from the server:
%1") .arg(jsonParseError.errorString()); } else { qCWarning(lcRemoteWipe) << QString("The reply from the server did not contain all expected fields."); } } _networkReplySuccess->deleteLater(); } }