diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 7588a6169..ed1820809 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -65,6 +65,8 @@ set(client_SRCS accountmanager.cpp accountsettings.h accountsettings.cpp + accountsetupcommandlinemanager.h + accountsetupcommandlinemanager.cpp application.h application.cpp invalidfilenamedialog.h diff --git a/src/gui/accountsetupcommandlinemanager.cpp b/src/gui/accountsetupcommandlinemanager.cpp new file mode 100644 index 000000000..dbc5c4604 --- /dev/null +++ b/src/gui/accountsetupcommandlinemanager.cpp @@ -0,0 +1,311 @@ +/* + * Copyright (C) by Oleksandr Zolotov + * + * 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 "accountsetupcommandlinemanager.h" + +#include "accountmanager.h" +#include "creds/webflowcredentials.h" +#include "filesystem.h" +#include "folder.h" +#include "folderman.h" +#include "networkjobs.h" + +#include +#include +#include +#include +#include +#include + +namespace OCC +{ +Q_LOGGING_CATEGORY(lcAccountSetupCommandLineManager, "nextcloud.gui.accountsetupcommandlinemanager", QtInfoMsg) + +AccountSetupFromCommandLineJob::AccountSetupFromCommandLineJob(QString appPassword, + QString userId, + QUrl serverUrl, + QString localDirPath, + bool nonVfsMode, + QString remoteDirPath, + QObject *parent) + : QObject(parent) + , _appPassword(appPassword) + , _userId(userId) + , _serverUrl(serverUrl) + , _localDirPath(localDirPath) + , _nonVfsMode(nonVfsMode) + , _remoteDirPath(remoteDirPath) +{ +} + +void AccountSetupFromCommandLineJob::handleAccountSetupFromCommandLine() +{ + if (AccountManager::instance()->accountFromUserId(QStringLiteral("%1@%2").arg(_userId).arg(_serverUrl.host()))) { + printAccountSetupFromCommandLineStatusAndExit(QStringLiteral("Account %1 already exists!").arg(QDir::toNativeSeparators(_userId)), true); + return; + } + + if (!_localDirPath.isEmpty()) { + QDir dir(_localDirPath); + if (dir.exists() && !dir.isEmpty()) { + printAccountSetupFromCommandLineStatusAndExit( + QStringLiteral("Local folder %1 already exists and is non-empty!").arg(QDir::toNativeSeparators(_localDirPath)), + true); + return; + } + + qCInfo(lcAccountSetupCommandLineManager) << "Creating folder" << _localDirPath; + if (!dir.exists() && !dir.mkpath(".")) { + printAccountSetupFromCommandLineStatusAndExit( + QStringLiteral("Folder creation failed. Could not create local folder %1").arg(QDir::toNativeSeparators(_localDirPath)), + true); + return; + } + + FileSystem::setFolderMinimumPermissions(_localDirPath); + Utility::setupFavLink(_localDirPath); + } + + const auto credentials = new WebFlowCredentials(_userId, _appPassword); + _account = AccountManager::createAccount(); + _account->setCredentials(credentials); + _account->setUrl(_serverUrl); + + fetchUserName(); +} + +void AccountSetupFromCommandLineJob::checkLastModifiedWithPropfind() +{ + const auto job = new PropfindJob(_account, "/", this); + job->setIgnoreCredentialFailure(true); + // There is custom redirect handling in the error handler, + // so don't automatically follow redirects. + job->setFollowRedirects(false); + job->setProperties(QList() << QByteArrayLiteral("getlastmodified")); + connect(job, &PropfindJob::result, this, &AccountSetupFromCommandLineJob::accountSetupFromCommandLinePropfindHandleSuccess); + connect(job, &PropfindJob::finishedWithError, this, &AccountSetupFromCommandLineJob::accountSetupFromCommandLinePropfindHandleFailure); + job->start(); +} + +void AccountSetupFromCommandLineJob::accountSetupFromCommandLinePropfindHandleSuccess() +{ + const auto accountManager = AccountManager::instance(); + const auto accountState = accountManager->addAccount(_account); + accountManager->save(); + + if (!_localDirPath.isEmpty()) { + FolderDefinition definition; + definition.localPath = _localDirPath; + definition.targetPath = FolderDefinition::prepareTargetPath(!_remoteDirPath.isEmpty() ? _remoteDirPath : QStringLiteral("/")); + definition.virtualFilesMode = _nonVfsMode ? Vfs::Off : bestAvailableVfsMode(); + + const auto folderMan = FolderMan::instance(); + + definition.ignoreHiddenFiles = folderMan->ignoreHiddenFiles(); + definition.alias = folderMan->map().size() > 0 ? QString::number(folderMan->map().size()) : QString::number(0); + + if (folderMan->navigationPaneHelper().showInExplorerNavigationPane()) { + definition.navigationPaneClsid = QUuid::createUuid(); + } + + folderMan->setSyncEnabled(false); + + if (const auto folder = folderMan->addFolder(accountState, definition)) { + if (definition.virtualFilesMode != Vfs::Off) { + folder->setRootPinState(PinState::OnlineOnly); + } + folder->journalDb()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncWhiteList, QStringList() << QLatin1String("/")); + qCInfo(lcAccountSetupCommandLineManager) << QStringLiteral("Folder %1 setup from command line success.").arg(definition.localPath); + printAccountSetupFromCommandLineStatusAndExit(QStringLiteral("Account %1 setup from command line success.").arg(_account->displayName()), false); + } else { + accountManager->deleteAccount(accountState); + printAccountSetupFromCommandLineStatusAndExit( + QStringLiteral("Account %1 setup from command line failed, due to folder creation failure.").arg(_account->displayName()), + false); + } + } else { + qCInfo(lcAccountSetupCommandLineManager) << QStringLiteral("Set up a new account without a folder."); + printAccountSetupFromCommandLineStatusAndExit(QStringLiteral("Account %1 setup from command line success.").arg(_account->displayName()), false); + } +} + +void AccountSetupFromCommandLineJob::accountSetupFromCommandLinePropfindHandleFailure() +{ + const auto job = qobject_cast(sender()); + if (!job) { + printAccountSetupFromCommandLineStatusAndExit(QStringLiteral("Cannot check for authed redirects. This slot should be invoked from PropfindJob!"), true); + return; + } + const auto reply = job->reply(); + + QString errorMsg; + + // If there were redirects on the *authed* requests, also store + // the updated server URL, similar to redirects on status.php. + QUrl redirectUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl(); + if (!redirectUrl.isEmpty()) { + qCInfo(lcAccountSetupCommandLineManager) << "Authed request was redirected to" << redirectUrl.toString(); + + // strip the expected path + auto path = redirectUrl.path(); + static QString expectedPath = "/" + _account->davPath(); + if (path.endsWith(expectedPath)) { + path.chop(expectedPath.size()); + redirectUrl.setPath(path); + + qCInfo(lcAccountSetupCommandLineManager) << "Setting account url to" << redirectUrl.toString(); + _account->setUrl(redirectUrl); + checkLastModifiedWithPropfind(); + } + errorMsg = tr("The authenticated request to the server was redirected to " + "\"%1\". The URL is bad, the server is misconfigured.") + .arg(Utility::escape(redirectUrl.toString())); + + // A 404 is actually a success: we were authorized to know that the folder does + // not exist. It will be created later... + } else if (reply->error() == QNetworkReply::ContentNotFoundError) { + accountSetupFromCommandLinePropfindHandleSuccess(); + } else if (reply->error() != QNetworkReply::NoError) { + if (!_account->credentials()->stillValid(reply)) { + errorMsg = tr("Access forbidden by server. To verify that you have proper access, " + "click here to access the service with your browser.") + .arg(Utility::escape(_account->url().toString())); + } else { + errorMsg = job->errorStringParsingBody(); + } + // Something else went wrong, maybe the response was 200 but with invalid data. + } else { + errorMsg = tr("There was an invalid response to an authenticated WebDAV request"); + } + printAccountSetupFromCommandLineStatusAndExit( + QStringLiteral("Account %1 setup from command line failed with error: %2.").arg(_account->displayName()).arg(errorMsg), + true); +} + +void AccountSetupFromCommandLineJob::printAccountSetupFromCommandLineStatusAndExit(const QString &status, bool isFailure) +{ + if (isFailure) { + qCWarning(lcAccountSetupCommandLineManager) << status; + } else { + qCInfo(lcAccountSetupCommandLineManager) << status; + } + QTimer::singleShot(0, this, [this, isFailure]() { + this->deleteLater(); + if (!isFailure) { + qApp->quit(); + } else { + qApp->exit(1); + } + }); +} + +void AccountSetupFromCommandLineJob::fetchUserName() +{ + const auto fetchUserNameJob = new JsonApiJob(_account, QStringLiteral("/ocs/v1.php/cloud/user")); + connect(fetchUserNameJob, &JsonApiJob::jsonReceived, this, [this](const QJsonDocument &json, int statusCode) { + sender()->deleteLater(); + + if (statusCode != 100) { + printAccountSetupFromCommandLineStatusAndExit("Could not fetch username.", true); + return; + } + + const auto objData = json.object().value("ocs").toObject().value("data").toObject(); + const auto userId = objData.value("id").toString(""); + const auto displayName = objData.value("display-name").toString(""); + _account->setDavUser(userId); + _account->setDavDisplayName(displayName); + + checkLastModifiedWithPropfind(); + }); + fetchUserNameJob->start(); +} + +bool AccountSetupCommandLineManager::parseCommandlineOption(const QString &option, QStringListIterator &optionsIterator, QString &errorMessage) +{ + if (option == QStringLiteral("--apppassword")) { + if (optionsIterator.hasNext() && !optionsIterator.peekNext().startsWith(QLatin1String("--"))) { + _appPassword = optionsIterator.next(); + return true; + } else { + errorMessage = QStringLiteral("apppassword not specified"); + } + } else if (option == QStringLiteral("--localdirpath")) { + if (optionsIterator.hasNext() && !optionsIterator.peekNext().startsWith(QLatin1String("--"))) { + _localDirPath = optionsIterator.next(); + return true; + } else { + errorMessage = QStringLiteral("basedir not specified"); + } + } else if (option == QStringLiteral("--remotedirpath")) { + if (optionsIterator.hasNext() && !optionsIterator.peekNext().startsWith(QLatin1String("--"))) { + _remoteDirPath = optionsIterator.next(); + return true; + } else { + errorMessage = QStringLiteral("remotedir not specified"); + } + } else if (option == QStringLiteral("--serverurl")) { + if (optionsIterator.hasNext() && !optionsIterator.peekNext().startsWith(QLatin1String("--"))) { + _serverUrl = optionsIterator.next(); + return true; + } else { + errorMessage = QStringLiteral("serverurl not specified"); + } + } else if (option == QStringLiteral("--userid")) { + if (optionsIterator.hasNext() && !optionsIterator.peekNext().startsWith(QLatin1String("--"))) { + _userId = optionsIterator.next(); + return true; + } else { + errorMessage = QStringLiteral("userid not specified"); + } + } else if (option == QLatin1String("--nonvfsmode")) { + if (optionsIterator.hasNext() && !optionsIterator.peekNext().startsWith(QLatin1String("--"))) { + _nonVfsMode = optionsIterator.next().toInt() != 0; + return true; + } else { + errorMessage = QStringLiteral("nonVfsMode not specified"); + } + } + return false; +} + +bool AccountSetupCommandLineManager::isCommandLineParsed() +{ + return !_appPassword.isEmpty() && !_userId.isEmpty() && _serverUrl.isValid(); +} + +void AccountSetupCommandLineManager::setupAccountFromCommandLine(QObject *parent) +{ + if (isCommandLineParsed()) { + qCInfo(lcAccountSetupCommandLineManager) << QStringLiteral("Command line has been parsed and account setup parameters have been found. Attempting setup a new account %1...").arg(_userId); + const auto accountSetupJob = new AccountSetupFromCommandLineJob(_appPassword, _userId, _serverUrl, _localDirPath, _nonVfsMode, _remoteDirPath, parent); + accountSetupJob->handleAccountSetupFromCommandLine(); + } else { + qCInfo(lcAccountSetupCommandLineManager) << QStringLiteral("No account setup parameters have been found, or they are invalid. Proceed with normal startup..."); + } + _appPassword.clear(); + _userId.clear(); + _serverUrl.clear(); + _remoteDirPath.clear(); + _localDirPath.clear(); + _nonVfsMode = false; +} + +QString AccountSetupCommandLineManager::_appPassword; +QString AccountSetupCommandLineManager::_userId; +QUrl AccountSetupCommandLineManager::_serverUrl; +QString AccountSetupCommandLineManager::_remoteDirPath; +QString AccountSetupCommandLineManager::_localDirPath; +bool AccountSetupCommandLineManager::_nonVfsMode = false; +} diff --git a/src/gui/accountsetupcommandlinemanager.h b/src/gui/accountsetupcommandlinemanager.h new file mode 100644 index 000000000..2875febdc --- /dev/null +++ b/src/gui/accountsetupcommandlinemanager.h @@ -0,0 +1,82 @@ +/* + * Copyright (C) by Oleksandr Zolotov + * + * 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. + */ + +#pragma once + +#include "account.h" +#include "accountstate.h" + +#include + +namespace OCC { + +class AccountSetupFromCommandLineJob : public QObject +{ + Q_OBJECT +public: + AccountSetupFromCommandLineJob(QString appPassword, + QString userId, + QUrl serverUrl, + QString localDirPath = {}, + bool nonVfsMode = false, + QString remoteDirPath = QStringLiteral("/"), + QObject *parent = nullptr); + +public slots: + void handleAccountSetupFromCommandLine(); + +private slots: + void checkLastModifiedWithPropfind(); + + void accountSetupFromCommandLinePropfindHandleSuccess(); + + void accountSetupFromCommandLinePropfindHandleFailure(); + + void printAccountSetupFromCommandLineStatusAndExit(const QString &status, bool isFailure); + + void fetchUserName(); + +private: + QString _appPassword; + QString _userId; + QUrl _serverUrl; + QString _localDirPath; + bool _nonVfsMode = false; + QString _remoteDirPath; + + AccountPtr _account; +}; + + +class AccountSetupCommandLineManager +{ +public: + [[nodiscard]] static bool parseCommandlineOption(const QString &option, QStringListIterator &optionsIterator, QString &errorMessage); + + [[nodiscard]] static bool isCommandLineParsed(); + + static void setupAccountFromCommandLine(QObject *parent = nullptr); + +private: + explicit AccountSetupCommandLineManager() = delete; + + static QString _appPassword; + static QString _userId; + static QUrl _serverUrl; + static QString _remoteDirPath; + static QString _localDirPath; + static bool _nonVfsMode; +}; + +} diff --git a/src/gui/application.cpp b/src/gui/application.cpp index 4106afe38..54d696ab8 100644 --- a/src/gui/application.cpp +++ b/src/gui/application.cpp @@ -21,10 +21,10 @@ #include "config.h" #include "account.h" +#include "accountsetupcommandlinemanager.h" #include "accountstate.h" #include "editlocallymanager.h" #include "connectionvalidator.h" -#include "filesystem.h" #include "folder.h" #include "folderman.h" #include "logger.h" @@ -35,7 +35,6 @@ #include "clientproxy.h" #include "accountmanager.h" #include "creds/abstractcredentials.h" -#include "creds/webflowcredentials.h" #include "pushnotifications.h" #include "shellextensionsserver.h" @@ -87,7 +86,13 @@ namespace { " --logflush : flush the log file after every write.\n" " --logdebug : also output debug-level messages in the log.\n" " --confdir : Use the given configuration folder.\n" - " --background : launch the application in the background.\n"; + " --background : launch the application in the background.\n" + " --userid : userId (username as on the server) to pass when creating an account via command-line.\n" + " --apppassword : appPassword to pass when creating an account via command-line.\n" + " --localdirpath : (optional) path where to create a local sync folder when creating an account via command-line.\n" + " --nonvfsmode : whether to set up a non-VFS folder (1 for 'yes' or 0 for 'no') when creating an account via command-line.\n" + " --remotedirpath : (optional) path to a remote subfolder when creating an account via command-line.\n" + " --serverurl : a server URL to use when creating an account via command-line.\n"; QString applicationTrPath() { @@ -414,8 +419,8 @@ Application::Application(int &argc, char **argv) handleEditLocallyFromOptions(); - if (!_appPassword.isEmpty() && !_userId.isEmpty() && !_baseDir.isEmpty() && _serverUrl.isValid()) { - handleAccountSetupFromCommandLine(); + if (AccountSetupCommandLineManager::isCommandLineParsed()) { + AccountSetupCommandLineManager::setupAccountFromCommandLine(this); } } @@ -585,6 +590,10 @@ void Application::slotParseMessage(const QString &msg, QObject *) handleEditLocallyFromOptions(); + if (AccountSetupCommandLineManager::isCommandLineParsed()) { + AccountSetupCommandLineManager::setupAccountFromCommandLine(this); + } + } else if (msg.startsWith(QLatin1String("MSG_SHOWMAINDIALOG"))) { qCInfo(lcApplication) << "Running for" << _startedAt.elapsed() / 1000.0 << "sec"; if (_startedAt.elapsed() < 10 * 1000) { @@ -669,39 +678,16 @@ void Application::parseOptions(const QStringList &options) qCInfo(lcApplication) << errorParsingLocalFileEditingUrl; showHint(errorParsingLocalFileEditingUrl.toStdString()); } - } else if (option == QLatin1String("--apppassword")) { - if (it.hasNext() && !it.peekNext().startsWith(QLatin1String("--"))) { - _appPassword = it.next(); - } else { - showHint("apppassword not specified"); - } - } else if (option == QLatin1String("--userid")) { - if (it.hasNext() && !it.peekNext().startsWith(QLatin1String("--"))) { - _userId = it.next(); - } else { - showHint("userid not specified"); - } - } else if (option == QLatin1String("--basedir")) { - if (it.hasNext() && !it.peekNext().startsWith(QLatin1String("--"))) { - _baseDir = it.next(); - } else { - showHint("basedir not specified"); - } - } else if (option == QLatin1String("--remotedir")) { - if (it.hasNext() && !it.peekNext().startsWith(QLatin1String("--"))) { - _remoteDir = it.next(); - } else { - showHint("remotedir not specified"); - } - } else if (option == QLatin1String("--serverurl")) { - if (it.hasNext() && !it.peekNext().startsWith(QLatin1String("--"))) { - _serverUrl = it.next(); - } else { - showHint("serverurl not specified"); - } - } + } else { - showHint("Unrecognized option '" + option.toStdString() + "'"); + QString errorMessage; + if (!AccountSetupCommandLineManager::parseCommandlineOption(option, it, errorMessage)) { + if (!errorMessage.isEmpty()) { + showHint(errorMessage.toStdString()); + return; + } + showHint("Unrecognized option '" + option.toStdString() + "'"); + } } } } @@ -885,184 +871,6 @@ void Application::slotGuiIsShowingSettings() emit isShowingSettingsDialog(); } -void Application::handleAccountSetupFromCommandLine() -{ - if (AccountManager::instance()->accountFromUserId(QStringLiteral("%1@%2").arg(_userId).arg(_serverUrl.host()))) { - printAccountSetupFromCommandLineStatusAndExit(QStringLiteral("Account %1 already exists!").arg(QDir::toNativeSeparators(_userId)), true); - return; - } - - QDir dir(_baseDir); - if (dir.exists() && !dir.isEmpty()) { - printAccountSetupFromCommandLineStatusAndExit(QStringLiteral("Local folder %1 already exists and is non-empty!").arg(QDir::toNativeSeparators(_baseDir)), true); - return; - } - - qInfo() << "Creating folder" << _baseDir; - if (!dir.exists() && !dir.mkpath(".")) { - printAccountSetupFromCommandLineStatusAndExit(QStringLiteral("Folder creation failed. Could not create local folder %1").arg(QDir::toNativeSeparators(_baseDir)), true); - return; - } - - FileSystem::setFolderMinimumPermissions(_baseDir); - Utility::setupFavLink(_baseDir); - - const auto credentials = new WebFlowCredentials(_userId, _appPassword); - _account = AccountManager::createAccount(); - _account->setCredentials(credentials); - _account->setUrl(_serverUrl); - - _userId.clear(); - _appPassword.clear(); - _serverUrl.clear(); - - fetchUserName(); -} - -void Application::checkLastModifiedWithPropfind() -{ - const auto job = new PropfindJob(_account, "/", this); - job->setIgnoreCredentialFailure(true); - // There is custom redirect handling in the error handler, - // so don't automatically follow redirects. - job->setFollowRedirects(false); - job->setProperties(QList() << "getlastmodified"); - connect(job, &PropfindJob::result, this, &Application::accountSetupFromCommandLinePropfindHandleSuccess); - connect(job, &PropfindJob::finishedWithError, this, &Application::accountSetupFromCommandLinePropfindHandleFailure); - job->start(); -} - -void Application::accountSetupFromCommandLinePropfindHandleSuccess() -{ - const auto accountManager = AccountManager::instance(); - const auto accountState = accountManager->addAccount(_account); - accountManager->save(); - - FolderDefinition definition; - definition.localPath = _baseDir; - definition.targetPath = FolderDefinition::prepareTargetPath(!_remoteDir.isEmpty() ? _remoteDir : QStringLiteral("/")); - definition.virtualFilesMode = bestAvailableVfsMode(); - - const auto folderMan = FolderMan::instance(); - - definition.ignoreHiddenFiles = folderMan->ignoreHiddenFiles(); - definition.alias = folderMan->map().size() > 0 ? QString::number(folderMan->map().size()) : QString::number(0); - - if (folderMan->navigationPaneHelper().showInExplorerNavigationPane()) { - definition.navigationPaneClsid = QUuid::createUuid(); - } - - folderMan->setSyncEnabled(false); - - if (const auto folder = folderMan->addFolder(accountState, definition)) { - if (definition.virtualFilesMode != Vfs::Off) { - folder->setRootPinState(PinState::OnlineOnly); - } - folder->journalDb()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncWhiteList, QStringList() << QLatin1String("/")); - qInfo() << QStringLiteral("Folder %1 setup from command line success.").arg(definition.localPath); - printAccountSetupFromCommandLineStatusAndExit(QStringLiteral("Account %1 setup from command line success.").arg(_account->displayName()), false); - } else { - accountManager->deleteAccount(accountState); - printAccountSetupFromCommandLineStatusAndExit(QStringLiteral("Account %1 setup from command line failed, due to folder creation failure.").arg(_account->displayName()), false); - } -} - -void Application::accountSetupFromCommandLinePropfindHandleFailure() -{ - const auto job = qobject_cast(sender()); - if (!job) { - printAccountSetupFromCommandLineStatusAndExit(QStringLiteral("Cannot check for authed redirects. This slot should be invoked from PropfindJob!"), true); - return; - } - const auto reply = job->reply(); - - QString errorMsg; - - // If there were redirects on the *authed* requests, also store - // the updated server URL, similar to redirects on status.php. - QUrl redirectUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl(); - if (!redirectUrl.isEmpty()) { - qInfo() << "Authed request was redirected to" << redirectUrl.toString(); - - // strip the expected path - auto path = redirectUrl.path(); - static QString expectedPath = "/" + _account->davPath(); - if (path.endsWith(expectedPath)) { - path.chop(expectedPath.size()); - redirectUrl.setPath(path); - - qInfo() << "Setting account url to" << redirectUrl.toString(); - _account->setUrl(redirectUrl); - checkLastModifiedWithPropfind(); - } - errorMsg = tr("The authenticated request to the server was redirected to " - "\"%1\". The URL is bad, the server is misconfigured.") - .arg(Utility::escape(redirectUrl.toString())); - - // A 404 is actually a success: we were authorized to know that the folder does - // not exist. It will be created later... - } else if (reply->error() == QNetworkReply::ContentNotFoundError) { - accountSetupFromCommandLinePropfindHandleSuccess(); - } else if (reply->error() != QNetworkReply::NoError) { - if (!_account->credentials()->stillValid(reply)) { - errorMsg = tr("Access forbidden by server. To verify that you have proper access, " - "click here to access the service with your browser.") - .arg(Utility::escape(_account->url().toString())); - } else { - errorMsg = job->errorStringParsingBody(); - } - // Something else went wrong, maybe the response was 200 but with invalid data. - } else { - errorMsg = tr("There was an invalid response to an authenticated WebDAV request"); - } - printAccountSetupFromCommandLineStatusAndExit( QStringLiteral("Account %1 setup from command line failed with error: %2.").arg(_account->displayName()).arg(errorMsg), true); -} - -void Application::printAccountSetupFromCommandLineStatusAndExit(const QString &status, bool isFailure) -{ - if (isFailure) { - qWarning() << status; - } else { - qInfo() << status; - } - _userId.clear(); - _appPassword.clear(); - _serverUrl.clear(); - _baseDir.clear(); - _remoteDir.clear(); - _account.clear(); - QTimer::singleShot(0, this, [isFailure]() { - if (isFailure) { - qApp->exit(1); - } else { - // we might need another wait to quit such that we won't end up with syncjournal being locked and lock not lifted - qApp->quit(); - } - }); -} - -void Application::fetchUserName() -{ - const auto fetchUserNameJob = new JsonApiJob(_account, QStringLiteral("/ocs/v1.php/cloud/user")); - connect(fetchUserNameJob, &JsonApiJob::jsonReceived, this, [this](const QJsonDocument &json, int statusCode) { - sender()->deleteLater(); - - if (statusCode != 100) { - printAccountSetupFromCommandLineStatusAndExit("Could not fetch username.", true); - return; - } - - const auto objData = json.object().value("ocs").toObject().value("data").toObject(); - const auto userId = objData.value("id").toString(""); - const auto displayName = objData.value("display-name").toString(""); - _account->setDavUser(userId); - _account->setDavDisplayName(displayName); - - checkLastModifiedWithPropfind(); - }); - fetchUserNameJob->start(); -} - void Application::openVirtualFile(const QString &filename) { QString virtualFileExt = QStringLiteral(APPLICATION_DOTVIRTUALFILE_SUFFIX); diff --git a/src/gui/application.h b/src/gui/application.h index c41b4cae4..5bd412077 100644 --- a/src/gui/application.h +++ b/src/gui/application.h @@ -107,14 +107,6 @@ protected slots: void slotSystemOnlineConfigurationChanged(QNetworkConfiguration); void slotGuiIsShowingSettings(); -private slots: - void handleAccountSetupFromCommandLine(); - void fetchUserName(); - void checkLastModifiedWithPropfind(); - void accountSetupFromCommandLinePropfindHandleSuccess(); - void accountSetupFromCommandLinePropfindHandleFailure(); - void printAccountSetupFromCommandLineStatusAndExit(const QString &status, bool isFailure); - private: void setHelp(); @@ -140,11 +132,6 @@ private: bool _quitInstance = false; QString _logFile; QString _logDir; - QString _appPassword; - QString _userId; - QString _baseDir; - QString _remoteDir; - QUrl _serverUrl; int _logExpire; bool _logFlush; bool _logDebug; @@ -158,8 +145,6 @@ private: QNetworkConfigurationManager _networkConfigurationManager; QTimer _checkConnectionTimer; - AccountPtr _account; - #if defined(WITH_CRASHREPORTER) QScopedPointer _crashHandler; #endif