From c8002bb94e0c80bbbcd8707637d834e514bb725b Mon Sep 17 00:00:00 2001 From: Matthieu Gallien Date: Mon, 25 Aug 2025 10:30:15 +0200 Subject: [PATCH] feat(proxy): store and modify proxy settings for use with new account connect the new UI to real proxy settings and allow modification and store them when the user has finished setting them up close #8602 Signed-off-by: Matthieu Gallien --- src/gui/CMakeLists.txt | 4 +- src/gui/owncloudsetupwizard.cpp | 36 ++++-- src/gui/owncloudsetupwizard.h | 4 +- src/gui/wizard/owncloudsetuppage.cpp | 19 +-- src/gui/wizard/owncloudsetuppage.h | 11 +- src/gui/wizard/owncloudwizard.h | 3 +- ...ings.cpp => wizardproxysettingsdialog.cpp} | 112 ++++++++++++------ ...settings.h => wizardproxysettingsdialog.h} | 30 ++--- 8 files changed, 136 insertions(+), 83 deletions(-) rename src/gui/wizard/{wizardproxysettings.cpp => wizardproxysettingsdialog.cpp} (53%) rename src/gui/wizard/{wizardproxysettings.h => wizardproxysettingsdialog.h} (51%) diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index a52e7d85fc..a9491e5be5 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -255,8 +255,8 @@ set(client_SRCS wizard/welcomepage.cpp wizard/linklabel.h wizard/linklabel.cpp - wizard/wizardproxysettings.h - wizard/wizardproxysettings.cpp + wizard/wizardproxysettingsdialog.h + wizard/wizardproxysettingsdialog.cpp ) if (NOT DISABLE_ACCOUNT_MIGRATION) diff --git a/src/gui/owncloudsetupwizard.cpp b/src/gui/owncloudsetupwizard.cpp index ba7ded88ec..0116b23901 100644 --- a/src/gui/owncloudsetupwizard.cpp +++ b/src/gui/owncloudsetupwizard.cpp @@ -146,20 +146,34 @@ void OwncloudSetupWizard::startWizard() } // also checks if an installation is valid and determines auth type in a second step -void OwncloudSetupWizard::slotCheckServer(const QString &urlString) +void OwncloudSetupWizard::slotCheckServer(const QUrl &serverURL, const OCC::WizardProxySettingsDialog::WizardProxySettings &proxySettings) { - QString fixedUrl = urlString; - QUrl url = QUrl::fromUserInput(fixedUrl); - // fromUserInput defaults to http, not http if no scheme is specified - if (!fixedUrl.startsWith("http://") && !fixedUrl.startsWith("https://")) { - url.setScheme("https"); - } AccountPtr account = _ocWizard->account(); - account->setUrl(url); + account->setUrl(serverURL); - // Reset the proxy which might had been determined previously in ConnectionValidator::checkServerAndAuth() - // when there was a previous account. - account->networkAccessManager()->setProxy(QNetworkProxy(QNetworkProxy::NoProxy)); + account->setProxyType(proxySettings._proxyType); + switch (proxySettings._proxyType) + { + case QNetworkProxy::HttpCachingProxy: + case QNetworkProxy::FtpCachingProxy: + case QNetworkProxy::NoProxy: + case QNetworkProxy::ProxyType::DefaultProxy: + // Reset the proxy which might had been determined previously in ConnectionValidator::checkServerAndAuth() + // when there was a previous account. + account->networkAccessManager()->setProxy({QNetworkProxy::NoProxy}); + break; + case QNetworkProxy::Socks5Proxy: + case QNetworkProxy::HttpProxy: + account->setProxyHostName(proxySettings._host); + account->setProxyPort(proxySettings._port); + account->setProxyNeedsAuth(proxySettings._needsAuth == WizardProxySettingsDialog::ProxyAuthentication::AuthenticationRequired); + if (account->proxyNeedsAuth()) { + account->setProxyUser(proxySettings._user); + account->setProxyPassword(proxySettings._password); + } + + break; + } // And also reset the QSslConfiguration, for the same reason (#6832) // Here the client certificate is added, if any. Later it'll be in HttpCredentials diff --git a/src/gui/owncloudsetupwizard.h b/src/gui/owncloudsetupwizard.h index af09ee2123..cdc64001fe 100644 --- a/src/gui/owncloudsetupwizard.h +++ b/src/gui/owncloudsetupwizard.h @@ -17,7 +17,7 @@ #include "theme.h" #include "networkjobs.h" -#include "wizard/owncloudwizardcommon.h" +#include "wizard/wizardproxysettingsdialog.h" namespace OCC { @@ -43,7 +43,7 @@ signals: void ownCloudWizardDone(int); private slots: - void slotCheckServer(const QString &); + void slotCheckServer(const QUrl &serverURL, const OCC::WizardProxySettingsDialog::WizardProxySettings &proxySettings); void slotSystemProxyLookupDone(const QNetworkProxy &proxy); void slotFindServer(); diff --git a/src/gui/wizard/owncloudsetuppage.cpp b/src/gui/wizard/owncloudsetuppage.cpp index e8a7b76abe..f504f2cc68 100644 --- a/src/gui/wizard/owncloudsetuppage.cpp +++ b/src/gui/wizard/owncloudsetuppage.cpp @@ -25,7 +25,7 @@ #include "wizard/owncloudwizardcommon.h" #include "wizard/owncloudsetuppage.h" #include "wizard/owncloudconnectionmethoddialog.h" -#include "wizard/slideshow.h" +#include "wizard/wizardproxysettingsdialog.h" #include "theme.h" #include "account.h" #include "config.h" @@ -190,8 +190,13 @@ void OwncloudSetupPage::slotUrlEditFinished() void OwncloudSetupPage::slotSetProxySettings() { - _proxySettingsDialog = new WizardProxySettings{QUrl::fromUserInput(_ui.leUrl->fullText()), this}; - _proxySettingsDialog->show(); + if (!_proxySettingsDialog) { + _proxySettingsDialog = new WizardProxySettingsDialog{QUrl::fromUserInput(_ui.leUrl->fullText()), _proxySettings, this}; + + connect(_proxySettingsDialog, &WizardProxySettingsDialog::proxySettingsAccepted, this, [this] (const OCC::WizardProxySettingsDialog::WizardProxySettings &proxySettings) { _proxySettings = proxySettings;}); + } + + _proxySettingsDialog->open(); } bool OwncloudSetupPage::isComplete() const @@ -291,8 +296,8 @@ bool OwncloudSetupPage::validatePage() { if (!_authTypeKnown) { slotUrlEditFinished(); - QString u = url(); - QUrl qurl(u); + const auto urlString = url(); + const auto qurl = QUrl::fromUserInput(urlString); if (!qurl.isValid() || qurl.host().isEmpty()) { setErrorString(tr("Server address does not seem to be valid"), false); return false; @@ -303,7 +308,7 @@ bool OwncloudSetupPage::validatePage() startSpinner(); emit completeChanged(); - emit determineAuthType(u); + Q_EMIT determineAuthType(qurl, _proxySettings); return false; } else { // connecting is running @@ -328,7 +333,7 @@ void OwncloudSetupPage::setErrorString(const QString &err, bool retryHTTPonly) } else { if (retryHTTPonly) { const auto urlString = url(); - QUrl url(urlString); + auto url = QUrl::fromUserInput(urlString); if (url.scheme() == "https") { // Ask the user how to proceed when connecting to a https:// URL fails. // It is possible that the server is secured with client-side TLS certificates, diff --git a/src/gui/wizard/owncloudsetuppage.h b/src/gui/wizard/owncloudsetuppage.h index 4edd1dd764..b5a0ccf6a7 100644 --- a/src/gui/wizard/owncloudsetuppage.h +++ b/src/gui/wizard/owncloudsetuppage.h @@ -9,17 +9,13 @@ #include -#include "wizard/owncloudwizardcommon.h" #include "wizard/owncloudwizard.h" #include "../addcertificatedialog.h" -#include "wizard/owncloudconnectionmethoddialog.h" -#include "wizard/wizardproxysettings.h" +#include "wizard/wizardproxysettingsdialog.h" #include "ui_owncloudsetupnocredspage.h" -#include "config.h" - class QLabel; class QVariant; class QProgressIndicator; @@ -65,7 +61,7 @@ protected slots: void setupCustomization(); signals: - void determineAuthType(const QString &); + void determineAuthType(const QUrl &serverURL, const OCC::WizardProxySettingsDialog::WizardProxySettings &proxySettings); private: void setLogo(); @@ -87,7 +83,8 @@ private: OwncloudWizard *_ocWizard; AddCertificateDialog *addCertDial = nullptr; - WizardProxySettings *_proxySettingsDialog = nullptr; + WizardProxySettingsDialog *_proxySettingsDialog = nullptr; + WizardProxySettingsDialog::WizardProxySettings _proxySettings; QMetaObject::Connection _proxyButtonIsConnected; // Grab the forceLoginV2-setting from the wizard diff --git a/src/gui/wizard/owncloudwizard.h b/src/gui/wizard/owncloudwizard.h index 76e41ede3a..c84840854f 100644 --- a/src/gui/wizard/owncloudwizard.h +++ b/src/gui/wizard/owncloudwizard.h @@ -15,6 +15,7 @@ #include "libsync/configfile.h" #include "networkjobs.h" #include "wizard/owncloudwizardcommon.h" +#include "wizard/wizardproxysettingsdialog.h" #include "accountfwd.h" namespace OCC { @@ -94,7 +95,7 @@ public slots: signals: void clearPendingRequests(); - void determineAuthType(const QString &); + void determineAuthType(const QUrl &serverURL, const OCC::WizardProxySettingsDialog::WizardProxySettings &proxySettings); void connectToOCUrl(const QString &); void createLocalAndRemoteFolders(const QString &, const QString &); // make sure to connect to this, rather than finished(int)!! diff --git a/src/gui/wizard/wizardproxysettings.cpp b/src/gui/wizard/wizardproxysettingsdialog.cpp similarity index 53% rename from src/gui/wizard/wizardproxysettings.cpp rename to src/gui/wizard/wizardproxysettingsdialog.cpp index 9f296aff01..a97d49c02c 100644 --- a/src/gui/wizard/wizardproxysettings.cpp +++ b/src/gui/wizard/wizardproxysettingsdialog.cpp @@ -3,7 +3,7 @@ * SPDX-License-Identifier: GPL-2.0-or-later */ -#include "wizardproxysettings.h" +#include "wizardproxysettingsdialog.h" #include #include @@ -12,9 +12,12 @@ namespace OCC { Q_LOGGING_CATEGORY(lcWizardProxySettings, "nextcloud.gui.wizard.proxysettings", QtInfoMsg) -WizardProxySettings::WizardProxySettings(QUrl serverURL, QWidget *parent) +WizardProxySettingsDialog::WizardProxySettingsDialog(QUrl serverURL, + WizardProxySettings proxySettings, + QWidget *parent) : QDialog(parent) - , _serverURL(std::move(serverURL)) + , _serverURL{std::move(serverURL)} + , _settings{std::move(proxySettings)} { _ui.setupUi(this); @@ -38,37 +41,68 @@ WizardProxySettings::WizardProxySettings(QUrl serverURL, QWidget *parent) connect(_ui.authRequiredcheckBox, &QAbstractButton::toggled, _ui.authWidgets, &QWidget::setEnabled); connect(_ui.manualProxyRadioButton, &QAbstractButton::toggled, _ui.manualSettings, &QWidget::setVisible); - connect(_ui.manualProxyRadioButton, &QAbstractButton::toggled, this, &WizardProxySettings::validateProxySettings); + connect(_ui.manualProxyRadioButton, &QAbstractButton::toggled, this, &WizardProxySettingsDialog::validateProxySettings); - connect(_ui.typeComboBox, static_cast(&QComboBox::currentIndexChanged), this, &WizardProxySettings::validateProxySettings); - connect(_ui.hostLineEdit, &QLineEdit::editingFinished, this, &WizardProxySettings::validateProxySettings); - connect(_ui.userLineEdit, &QLineEdit::editingFinished, this, &WizardProxySettings::validateProxySettings); - connect(_ui.passwordLineEdit, &QLineEdit::editingFinished, this, &WizardProxySettings::validateProxySettings); - connect(_ui.portSpinBox, &QAbstractSpinBox::editingFinished, this, &WizardProxySettings::validateProxySettings); - connect(_ui.authRequiredcheckBox, &QAbstractButton::toggled, this, &WizardProxySettings::validateProxySettings); + connect(_ui.typeComboBox, static_cast(&QComboBox::currentIndexChanged), this, &WizardProxySettingsDialog::validateProxySettings); + connect(_ui.hostLineEdit, &QLineEdit::editingFinished, this, &WizardProxySettingsDialog::validateProxySettings); + connect(_ui.userLineEdit, &QLineEdit::editingFinished, this, &WizardProxySettingsDialog::validateProxySettings); + connect(_ui.passwordLineEdit, &QLineEdit::editingFinished, this, &WizardProxySettingsDialog::validateProxySettings); + connect(_ui.portSpinBox, &QAbstractSpinBox::editingFinished, this, &WizardProxySettingsDialog::validateProxySettings); + connect(_ui.authRequiredcheckBox, &QAbstractButton::toggled, this, &WizardProxySettingsDialog::validateProxySettings); // Warn about empty proxy host - connect(_ui.hostLineEdit, &QLineEdit::textChanged, this, &WizardProxySettings::checkEmptyProxyHost); - connect(_ui.hostLineEdit, &QLineEdit::textChanged, this, &WizardProxySettings::validateProxySettings); + connect(_ui.hostLineEdit, &QLineEdit::textChanged, this, &WizardProxySettingsDialog::checkEmptyProxyHost); + connect(_ui.hostLineEdit, &QLineEdit::textChanged, this, &WizardProxySettingsDialog::validateProxySettings); - connect(_ui.userLineEdit, &QLineEdit::textChanged, this, &WizardProxySettings::checkEmptyProxyCredentials); - connect(_ui.passwordLineEdit, &QLineEdit::textChanged, this, &WizardProxySettings::checkEmptyProxyCredentials); - connect(_ui.authRequiredcheckBox, &QAbstractButton::toggled, this, &WizardProxySettings::checkEmptyProxyCredentials); + connect(_ui.userLineEdit, &QLineEdit::textChanged, this, &WizardProxySettingsDialog::checkEmptyProxyCredentials); + connect(_ui.passwordLineEdit, &QLineEdit::textChanged, this, &WizardProxySettingsDialog::checkEmptyProxyCredentials); + connect(_ui.authRequiredcheckBox, &QAbstractButton::toggled, this, &WizardProxySettingsDialog::checkEmptyProxyCredentials); connect(_ui.buttonBox, &QDialogButtonBox::accepted, - this, &WizardProxySettings::settingsDone); + this, &WizardProxySettingsDialog::settingsDone); connect(_ui.buttonBox, &QDialogButtonBox::rejected, - this, &WizardProxySettings::reject); + this, &WizardProxySettingsDialog::reject); checkEmptyProxyHost(); checkAccountLocalhost(); - _ui.noProxyRadioButton->setChecked(true); - _ui.noProxyRadioButton->setFocus(); - _ui.manualSettings->setVisible(false); + if (!_settings._user.isEmpty()) { + _ui.userLineEdit->setText(_settings._user); + } + if (!_settings._password.isEmpty()) { + _ui.passwordLineEdit->setText(_settings._password); + } + if (!_settings._host.isEmpty()) { + _ui.hostLineEdit->setText(_settings._host); + } + + _ui.authRequiredcheckBox->setChecked(_settings._needsAuth != ProxyAuthentication::NoAuthentication); + + switch (_settings._proxyType) + { + case QNetworkProxy::NoProxy: + _ui.noProxyRadioButton->setChecked(true); + _ui.noProxyRadioButton->setFocus(); + _ui.manualSettings->setVisible(false); + break; + case QNetworkProxy::ProxyType::DefaultProxy: + _ui.systemProxyRadioButton->setChecked(true); + _ui.systemProxyRadioButton->setFocus(); + _ui.manualSettings->setVisible(false); + break; + case QNetworkProxy::Socks5Proxy: + case QNetworkProxy::HttpProxy: + _ui.manualProxyRadioButton->setChecked(true); + _ui.manualProxyRadioButton->setFocus(); + _ui.manualSettings->setVisible(true); + break; + case QNetworkProxy::HttpCachingProxy: + case QNetworkProxy::FtpCachingProxy: + break; + } } -void WizardProxySettings::checkEmptyProxyHost() +void WizardProxySettingsDialog::checkEmptyProxyHost() { if (_ui.hostLineEdit->isEnabled() && _ui.hostLineEdit->text().isEmpty()) { _ui.hostLineEdit->setStyleSheet("border: 1px solid red"); @@ -77,7 +111,7 @@ void WizardProxySettings::checkEmptyProxyHost() } } -void WizardProxySettings::checkEmptyProxyCredentials() +void WizardProxySettingsDialog::checkEmptyProxyCredentials() { if (!_ui.authRequiredcheckBox->isChecked()) { _ui.userLineEdit->setStyleSheet(QString()); @@ -98,7 +132,7 @@ void WizardProxySettings::checkEmptyProxyCredentials() } } -void WizardProxySettings::checkAccountLocalhost() +void WizardProxySettingsDialog::checkAccountLocalhost() { auto visible = false; if (_ui.manualProxyRadioButton->isChecked()) { @@ -111,34 +145,34 @@ void WizardProxySettings::checkAccountLocalhost() _ui.labelLocalhost->setVisible(visible); } -void WizardProxySettings::validateProxySettings() +void WizardProxySettingsDialog::validateProxySettings() { checkEmptyProxyHost(); - _user = _ui.userLineEdit->text(); - _password = _ui.passwordLineEdit->text(); - _host = _ui.hostLineEdit->text(); - _port = _ui.portSpinBox->value(); - _needsAuth = _ui.authRequiredcheckBox->isChecked() ? ProxyAuthentication::AuthenticationRequired : ProxyAuthentication::NoAuthentication; + _settings._user = _ui.userLineEdit->text(); + _settings._password = _ui.passwordLineEdit->text(); + _settings._host = _ui.hostLineEdit->text(); + _settings._port = _ui.portSpinBox->value(); + _settings._needsAuth = _ui.authRequiredcheckBox->isChecked() ? ProxyAuthentication::AuthenticationRequired : ProxyAuthentication::NoAuthentication; - _proxyType = QNetworkProxy::NoProxy; + _settings._proxyType = QNetworkProxy::NoProxy; _valid = false; if (_ui.noProxyRadioButton->isChecked()) { - _proxyType = QNetworkProxy::NoProxy; + _settings._proxyType = QNetworkProxy::NoProxy; _valid = true; } else if (_ui.systemProxyRadioButton->isChecked()) { - _proxyType = QNetworkProxy::DefaultProxy; + _settings._proxyType = QNetworkProxy::DefaultProxy; _valid = true; } else if (_ui.manualProxyRadioButton->isChecked()) { - _proxyType = _ui.typeComboBox->itemData(_ui.typeComboBox->currentIndex()).value(); + _settings._proxyType = _ui.typeComboBox->itemData(_ui.typeComboBox->currentIndex()).value(); _valid = true; - if (_host.isEmpty()) { - _proxyType = QNetworkProxy::NoProxy; + if (_settings._host.isEmpty()) { + _settings._proxyType = QNetworkProxy::NoProxy; _valid = false; } - if (_ui.authRequiredcheckBox->isChecked() && (_user.isEmpty() || _password.isEmpty())) { - _proxyType = QNetworkProxy::NoProxy; + if (_ui.authRequiredcheckBox->isChecked() && (_settings._user.isEmpty() || _settings._password.isEmpty())) { + _settings._proxyType = QNetworkProxy::NoProxy; _valid = false; } } @@ -149,9 +183,9 @@ void WizardProxySettings::validateProxySettings() } } -void WizardProxySettings::settingsDone() +void WizardProxySettingsDialog::settingsDone() { - Q_EMIT proxySettingsAccepted(_user, _password, _host, _port, _needsAuth, _proxyType); + Q_EMIT proxySettingsAccepted(_settings); accept(); } diff --git a/src/gui/wizard/wizardproxysettings.h b/src/gui/wizard/wizardproxysettingsdialog.h similarity index 51% rename from src/gui/wizard/wizardproxysettings.h rename to src/gui/wizard/wizardproxysettingsdialog.h index 9305d8f725..ad30d841a8 100644 --- a/src/gui/wizard/wizardproxysettings.h +++ b/src/gui/wizard/wizardproxysettingsdialog.h @@ -12,7 +12,7 @@ namespace OCC { -class WizardProxySettings : public QDialog +class WizardProxySettingsDialog : public QDialog { Q_OBJECT public: @@ -21,15 +21,22 @@ public: NoAuthentication, }; - explicit WizardProxySettings(QUrl serverURL, QWidget *parent = nullptr); + struct WizardProxySettings + { + QString _user; + QString _password; + QString _host; + quint16 _port; + ProxyAuthentication _needsAuth = ProxyAuthentication::NoAuthentication; + QNetworkProxy::ProxyType _proxyType = QNetworkProxy::NoProxy; + }; + + explicit WizardProxySettingsDialog(QUrl serverURL, + WizardProxySettings proxySettings, + QWidget *parent = nullptr); Q_SIGNALS: - void proxySettingsAccepted(QString user, - QString password, - QString host, - int port, - WizardProxySettings::ProxyAuthentication needsAuth, - QNetworkProxy::ProxyType proxyType); + void proxySettingsAccepted(const OCC::WizardProxySettingsDialog::WizardProxySettings &proxySettings); private Q_SLOTS: /// Red marking of host field if empty and enabled @@ -50,12 +57,7 @@ private: bool _valid = false; - QString _user; - QString _password; - QString _host; - int _port; - ProxyAuthentication _needsAuth = ProxyAuthentication::NoAuthentication; - QNetworkProxy::ProxyType _proxyType = QNetworkProxy::NoProxy; + WizardProxySettings _settings; }; }