diff --git a/src/gui/accountmanager.cpp b/src/gui/accountmanager.cpp index 00098bc86..41ad72efe 100644 --- a/src/gui/accountmanager.cpp +++ b/src/gui/accountmanager.cpp @@ -69,7 +69,7 @@ AccountManager *AccountManager::instance() return &instance; } -bool AccountManager::restore() +bool AccountManager::restore(bool alsoRestoreLegacySettings) { QStringList skipSettingsKeys; backwardMigrationSettingsKeys(&skipSettingsKeys, &skipSettingsKeys); @@ -88,8 +88,7 @@ bool AccountManager::restore() } // If there are no accounts, check the old format. - if (settings->childGroups().isEmpty() - && !settings->contains(QLatin1String(versionC))) { + if (settings->childGroups().isEmpty() && !settings->contains(QLatin1String(versionC)) && alsoRestoreLegacySettings) { restoreFromLegacySettings(); return true; } diff --git a/src/gui/accountmanager.h b/src/gui/accountmanager.h index 574197af9..c1c56c7cc 100644 --- a/src/gui/accountmanager.h +++ b/src/gui/accountmanager.h @@ -41,7 +41,7 @@ public: * Returns false if there was an error reading the settings, * but note that settings not existing is not an error. */ - bool restore(); + bool restore(bool alsoRestoreLegacySettings = true); /** * Add this account in the list of saved accounts. diff --git a/src/gui/application.cpp b/src/gui/application.cpp index 8af99a7df..3a262a305 100644 --- a/src/gui/application.cpp +++ b/src/gui/application.cpp @@ -87,6 +87,8 @@ namespace { " --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" + " --overrideserverurl : specify a server URL to use for the force override to be used in the account setup wizard.\n" + " --overridelocaldir : specify a local dir to be used in the account setup wizard.\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" @@ -335,12 +337,12 @@ Application::Application(int &argc, char **argv) connect(this, &SharedTools::QtSingleApplication::messageReceived, this, &Application::slotParseMessage); - if (!AccountManager::instance()->restore()) { + if (!AccountManager::instance()->restore(cfg.overrideServerUrl().isEmpty())) { // If there is an error reading the account settings, try again // after a couple of seconds, if that fails, give up. // (non-existence is not an error) Utility::sleep(5); - if (!AccountManager::instance()->restore()) { + if (!AccountManager::instance()->restore(cfg.overrideServerUrl().isEmpty())) { qCCritical(lcApplication) << "Could not read the account settings, quitting"; QMessageBox::critical( nullptr, @@ -620,6 +622,8 @@ void Application::parseOptions(const QStringList &options) if (it.hasNext()) it.next(); + bool shouldExit = false; + //parse options; if help or bad option exit while (it.hasNext()) { QString option = it.next(); @@ -680,6 +684,26 @@ void Application::parseOptions(const QStringList &options) qCInfo(lcApplication) << errorParsingLocalFileEditingUrl; showHint(errorParsingLocalFileEditingUrl.toStdString()); } + } else if (option == QStringLiteral("--overrideserverurl")) { + if (it.hasNext() && !it.peekNext().startsWith(QLatin1String("--"))) { + const auto overrideUrl = it.next(); + const auto isUrlValid = (overrideUrl.startsWith(QStringLiteral("http://")) || overrideUrl.startsWith(QStringLiteral("https://"))) + && QUrl::fromUserInput(overrideUrl).isValid(); + if (!isUrlValid) { + showHint("Invalid URL passed to --overrideserverurl"); + } else { + ConfigFile().setOverrideServerUrl(overrideUrl); + shouldExit = true; + } + } else { + showHint("Invalid URL passed to --overrideserverurl"); + } + } else if (option == QStringLiteral("--overridelocaldir")) { + if (it.hasNext() && !it.peekNext().startsWith(QLatin1String("--"))) { + ConfigFile().setOverrideLocalDir(it.next()); + } else { + showHint("Invalid URL passed to --overridelocaldir"); + } } else { QString errorMessage; @@ -692,6 +716,9 @@ void Application::parseOptions(const QStringList &options) } } } + if (shouldExit) { + std::exit(0); + } } // Helpers for displaying messages. Note that there is no console on Windows. diff --git a/src/gui/owncloudsetupwizard.cpp b/src/gui/owncloudsetupwizard.cpp index 0ce78f58e..27f7d6c9f 100644 --- a/src/gui/owncloudsetupwizard.cpp +++ b/src/gui/owncloudsetupwizard.cpp @@ -69,6 +69,12 @@ static QPointer wiz = nullptr; void OwncloudSetupWizard::runWizard(QObject *obj, const char *amember, QWidget *parent) { + ConfigFile cfg; + if (!cfg.overrideServerUrl().isEmpty()) { + Theme::instance()->setOverrideServerUrl(cfg.overrideServerUrl()); + Theme::instance()->setForceOverrideServerUrl(true); + Theme::instance()->setStartLoginFlowAutomatically(true); + } if (!wiz.isNull()) { bringWizardToFrontIfVisible(); return; @@ -109,6 +115,12 @@ void OwncloudSetupWizard::startWizard() } _ocWizard->setProperty("localFolder", localFolder); + { + ConfigFile cfg; + if (!cfg.overrideLocalDir().isEmpty()) { + _ocWizard->setProperty("localFolder", cfg.overrideLocalDir()); + } + } // remember the local folder to compare later if it changed, but clean first QString lf = QDir::fromNativeSeparators(localFolder); @@ -120,8 +132,11 @@ void OwncloudSetupWizard::startWizard() _ocWizard->setRemoteFolder(_remoteFolder); + const auto isEnforcedServerSetup = + Theme::instance()->startLoginFlowAutomatically() && Theme::instance()->forceOverrideServerUrl() && !account->url().isEmpty(); + #ifdef WITH_PROVIDERS - const auto startPage = WizardCommon::Page_Welcome; + const auto startPage = isEnforcedServerSetup ? WizardCommon::Page_ServerSetup : WizardCommon::Page_Welcome; #else // WITH_PROVIDERS const auto startPage = WizardCommon::Page_ServerSetup; #endif // WITH_PROVIDERS diff --git a/src/gui/wizard/owncloudadvancedsetuppage.cpp b/src/gui/wizard/owncloudadvancedsetuppage.cpp index 668a0171a..7e49980ed 100644 --- a/src/gui/wizard/owncloudadvancedsetuppage.cpp +++ b/src/gui/wizard/owncloudadvancedsetuppage.cpp @@ -193,6 +193,16 @@ void OwncloudAdvancedSetupPage::initializePage() if (nextButton) { nextButton->setDefault(true); } + if (Theme::instance()->forceOverrideServerUrl()) { + QTimer::singleShot(0, this, [this]() { + connect(_ocWizard, &QDialog::accepted, []() { + ConfigFile cfg; + cfg.setOverrideServerUrl({}); + cfg.setOverrideLocalDir({}); + }); + _ocWizard->accept(); + }); + } } void OwncloudAdvancedSetupPage::fetchUserAvatar() diff --git a/src/libsync/configfile.cpp b/src/libsync/configfile.cpp index a72933431..08064026f 100644 --- a/src/libsync/configfile.cpp +++ b/src/libsync/configfile.cpp @@ -67,6 +67,8 @@ static constexpr char autoUpdateCheckC[] = "autoUpdateCheck"; static constexpr char updateCheckIntervalC[] = "updateCheckInterval"; static constexpr char updateSegmentC[] = "updateSegment"; static constexpr char updateChannelC[] = "updateChannel"; +static constexpr char overrideServerUrlC[] = "overrideServerUrl"; +static constexpr char overrideLocalDirC[] = "overrideLocalDir"; static constexpr char geometryC[] = "geometry"; static constexpr char timeoutC[] = "timeout"; static constexpr char chunkSizeC[] = "chunkSize"; @@ -688,6 +690,30 @@ void ConfigFile::setUpdateChannel(const QString &channel) settings.setValue(QLatin1String(updateChannelC), channel); } +[[nodiscard]] QString ConfigFile::overrideServerUrl() const +{ + QSettings settings(configFile(), QSettings::IniFormat); + return settings.value(QLatin1String(overrideServerUrlC), {}).toString(); +} + +void ConfigFile::setOverrideServerUrl(const QString &url) +{ + QSettings settings(configFile(), QSettings::IniFormat); + settings.setValue(QLatin1String(overrideServerUrlC), url); +} + +[[nodiscard]] QString ConfigFile::overrideLocalDir() const +{ + QSettings settings(configFile(), QSettings::IniFormat); + return settings.value(QLatin1String(overrideLocalDirC), {}).toString(); +} + +void ConfigFile::setOverrideLocalDir(const QString &localDir) +{ + QSettings settings(configFile(), QSettings::IniFormat); + settings.setValue(QLatin1String(overrideLocalDirC), localDir); +} + void ConfigFile::setProxyType(int proxyType, const QString &host, int port, bool needsAuth, diff --git a/src/libsync/configfile.h b/src/libsync/configfile.h index e731f3016..719cce083 100644 --- a/src/libsync/configfile.h +++ b/src/libsync/configfile.h @@ -186,6 +186,12 @@ public: [[nodiscard]] QString updateChannel() const; void setUpdateChannel(const QString &channel); + [[nodiscard]] QString overrideServerUrl() const; + void setOverrideServerUrl(const QString &url); + + [[nodiscard]] QString overrideLocalDir() const; + void setOverrideLocalDir(const QString &localDir); + void saveGeometryHeader(QHeaderView *header); void restoreGeometryHeader(QHeaderView *header); diff --git a/src/libsync/theme.cpp b/src/libsync/theme.cpp index a28558b49..caee23bc3 100644 --- a/src/libsync/theme.cpp +++ b/src/libsync/theme.cpp @@ -371,6 +371,13 @@ Theme::Theme() reserveDarkPalette.setColor(QPalette::Disabled, QPalette::HighlightedText, QColor(127, 127, 127)); #endif + +#ifdef APPLICATION_SERVER_URL_ENFORCE + _forceOverrideServerUrl = true; +#endif +#ifdef APPLICATION_SERVER_URL + _overrideServerUrl = QString::fromLatin1(APPLICATION_SERVER_URL); +#endif } // If this option returns true, the client only supports one folder to sync. @@ -411,20 +418,17 @@ QString Theme::conflictHelpUrl() const QString Theme::overrideServerUrl() const { -#ifdef APPLICATION_SERVER_URL - return QString::fromLatin1(APPLICATION_SERVER_URL); -#else - return QString(); -#endif + return _overrideServerUrl; } bool Theme::forceOverrideServerUrl() const { -#ifdef APPLICATION_SERVER_URL_ENFORCE - return true; -#else - return false; -#endif + return _forceOverrideServerUrl; +} + +bool Theme::startLoginFlowAutomatically() const +{ + return _startLoginFlowAutomatically; } bool Theme::enableStaplingOCSP() const @@ -952,4 +956,27 @@ bool Theme::darkMode() #endif } +void Theme::setOverrideServerUrl(const QString &overrideServerUrl) +{ + if (_overrideServerUrl != overrideServerUrl) { + _overrideServerUrl = overrideServerUrl; + emit overrideServerUrlChanged(); + } +} +void Theme::setForceOverrideServerUrl(bool forceOverride) +{ + if (_forceOverrideServerUrl != forceOverride) { + _forceOverrideServerUrl = forceOverride; + emit forceOverrideServerUrlChanged(); + } +} + +void Theme::setStartLoginFlowAutomatically(bool startLoginFlowAuto) +{ + if (_startLoginFlowAutomatically != startLoginFlowAuto) { + _startLoginFlowAutomatically = startLoginFlowAuto; + emit startLoginFlowAutomaticallyChanged(); + } +} + } // end namespace client diff --git a/src/libsync/theme.h b/src/libsync/theme.h index db86b282b..de721f71c 100644 --- a/src/libsync/theme.h +++ b/src/libsync/theme.h @@ -55,8 +55,9 @@ class OWNCLOUDSYNC_EXPORT Theme : public QObject Q_PROPERTY(QString version READ version CONSTANT) Q_PROPERTY(QString helpUrl READ helpUrl CONSTANT) Q_PROPERTY(QString conflictHelpUrl READ conflictHelpUrl CONSTANT) - Q_PROPERTY(QString overrideServerUrl READ overrideServerUrl CONSTANT) - Q_PROPERTY(bool forceOverrideServerUrl READ forceOverrideServerUrl CONSTANT) + Q_PROPERTY(QString overrideServerUrl READ overrideServerUrl WRITE setOverrideServerUrl NOTIFY overrideServerUrlChanged) + Q_PROPERTY(bool forceOverrideServerUrl READ forceOverrideServerUrl WRITE setForceOverrideServerUrl NOTIFY forceOverrideServerUrlChanged) + Q_PROPERTY(bool startLoginFlowAutomatically READ startLoginFlowAutomatically WRITE setStartLoginFlowAutomatically NOTIFY startLoginFlowAutomaticallyChanged) #ifndef TOKEN_AUTH_ONLY Q_PROPERTY(QColor wizardHeaderTitleColor READ wizardHeaderTitleColor CONSTANT) Q_PROPERTY(QColor wizardHeaderBackgroundColor READ wizardHeaderBackgroundColor CONSTANT) @@ -241,6 +242,13 @@ public: * When true, the respective UI controls will be disabled */ virtual bool forceOverrideServerUrl() const; + + /** + * Automatically start login flow + * + * When true, the browser will get opened automatically + */ + virtual bool startLoginFlowAutomatically() const; /** * Enable OCSP stapling for SSL handshakes @@ -584,6 +592,11 @@ public: QPalette systemPalette(); bool darkMode(); +public slots: + virtual void setOverrideServerUrl(const QString &overrideServerUrl); + virtual void setForceOverrideServerUrl(bool forceOverride); + virtual void setStartLoginFlowAutomatically(bool startLoginFlowAuto); + protected: #ifndef TOKEN_AUTH_ONLY QIcon themeIcon(const QString &name, bool sysTray = false) const; @@ -602,6 +615,9 @@ signals: void systrayUseMonoIconsChanged(bool); void systemPaletteChanged(const QPalette &palette); void darkModeChanged(); + void overrideServerUrlChanged(); + void forceOverrideServerUrlChanged(); + void startLoginFlowAutomaticallyChanged(); private: Theme(Theme const &); @@ -616,6 +632,10 @@ private: bool _mono = false; bool _paletteSignalsConnected = false; + QString _overrideServerUrl; + bool _forceOverrideServerUrl = false; + bool _startLoginFlowAutomatically = false; + #ifndef TOKEN_AUTH_ONLY mutable QHash _iconCache; #endif