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 <matthieu.gallien@nextcloud.com>
This commit is contained in:
Matthieu Gallien 2025-08-25 10:30:15 +02:00
parent 7f599dc917
commit c8002bb94e
No known key found for this signature in database
GPG Key ID: 7D0F74F05C22F553
8 changed files with 136 additions and 83 deletions

View File

@ -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)

View File

@ -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

View File

@ -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();

View File

@ -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,

View File

@ -9,17 +9,13 @@
#include <QWizard>
#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

View File

@ -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)!!

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "wizardproxysettings.h"
#include "wizardproxysettingsdialog.h"
#include <QPushButton>
#include <QLoggingCategory>
@ -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<void (QComboBox::*)(int)>(&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<void (QComboBox::*)(int)>(&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<QNetworkProxy::ProxyType>();
_settings._proxyType = _ui.typeComboBox->itemData(_ui.typeComboBox->currentIndex()).value<QNetworkProxy::ProxyType>();
_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();
}

View File

@ -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;
};
}