Merge pull request #10441 from f321x/fix_10437
Wizard/qt/qml: validate server address input, fix #10437
This commit is contained in:
@@ -39,6 +39,7 @@ ElDialog {
|
||||
FlatButton {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr('Ok')
|
||||
enabled: serverconfig.addressValid
|
||||
icon.source: '../../icons/confirmed.png'
|
||||
onClicked: {
|
||||
let auto_connect = serverconfig.serverConnectMode == ServerConnectModeComboBox.Mode.Autoconnect
|
||||
|
||||
@@ -12,6 +12,7 @@ Item {
|
||||
property bool showAutoselectServer: true
|
||||
property alias address: address_tf.text
|
||||
property alias serverConnectMode: server_connect_mode_cb.currentValue
|
||||
property alias addressValid: address_tf.valid
|
||||
|
||||
implicitHeight: rootLayout.height
|
||||
|
||||
@@ -28,6 +29,11 @@ Item {
|
||||
|
||||
ServerConnectModeComboBox {
|
||||
id: server_connect_mode_cb
|
||||
onCurrentValueChanged: {
|
||||
if (currentValue == ServerConnectModeComboBox.Mode.Autoconnect) {
|
||||
address_tf.text = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
@@ -63,6 +69,26 @@ Item {
|
||||
enabled: server_connect_mode_cb.currentValue != ServerConnectModeComboBox.Mode.Autoconnect
|
||||
width: parent.width
|
||||
inputMethodHints: Qt.ImhNoPredictiveText
|
||||
|
||||
property bool valid: true
|
||||
|
||||
function validate() {
|
||||
if (!enabled) {
|
||||
valid = true
|
||||
return
|
||||
}
|
||||
valid = Network.isValidServerAddress(address_tf.text)
|
||||
}
|
||||
|
||||
onTextChanged: validate()
|
||||
onEnabledChanged: validate()
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: "red"
|
||||
opacity: 0.2
|
||||
visible: !parent.valid
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import QtQuick.Controls
|
||||
import "../controls"
|
||||
|
||||
WizardComponent {
|
||||
valid: true
|
||||
valid: sc.addressValid
|
||||
last: true
|
||||
title: qsTr('Server')
|
||||
|
||||
|
||||
@@ -206,6 +206,10 @@ class QENetwork(QObject, QtEventListener):
|
||||
def server(self):
|
||||
return self._server
|
||||
|
||||
@pyqtSlot(str, result=bool)
|
||||
def isValidServerAddress(self, server: str) -> bool:
|
||||
return ServerAddr.from_str_with_inference(server) is not None
|
||||
|
||||
@pyqtSlot(str, bool, bool)
|
||||
def setServerParameters(self, server_str: str, auto_connect: bool, one_server: bool):
|
||||
net_params = self.network.get_parameters()
|
||||
|
||||
@@ -361,6 +361,8 @@ class ServerWidget(QWidget, QtEventListener):
|
||||
ConnectMode.ONESERVER: messages.MSG_CONNECTMODE_ONESERVER,
|
||||
}
|
||||
|
||||
server_e_valid = pyqtSignal(bool)
|
||||
|
||||
def __init__(self, network: Network, parent=None):
|
||||
super().__init__(parent)
|
||||
self.network = network
|
||||
@@ -390,6 +392,7 @@ class ServerWidget(QWidget, QtEventListener):
|
||||
grid.addWidget(self.connect_combo, 0, 1, 1, 3)
|
||||
|
||||
self.server_e = QLineEdit()
|
||||
self.server_e.textChanged.connect(self.validate_server_e)
|
||||
self.server_e.editingFinished.connect(self.on_server_settings_changed)
|
||||
grid.addWidget(QLabel(_('Server') + ':'), 1, 0)
|
||||
grid.addWidget(self.server_e, 1, 1, 1, 3)
|
||||
@@ -502,6 +505,7 @@ class ServerWidget(QWidget, QtEventListener):
|
||||
self.status_label_header, self.status_label, self.status_label_helpbutton,
|
||||
self.height_label_header, self.height_label, self.height_label_helpbutton]:
|
||||
item.setVisible(self.network._was_started)
|
||||
self.validate_server_e()
|
||||
msg = _('Fork detection disabled') if self.is_one_server() else ''
|
||||
if self.network._was_started:
|
||||
# Network was started, so we don't run in initial setup wizard.
|
||||
@@ -522,6 +526,15 @@ class ServerWidget(QWidget, QtEventListener):
|
||||
msg += _('Your server is on branch {0} ({1} blocks)').format(name, chain.get_branch_size())
|
||||
self.split_label.setText(msg)
|
||||
|
||||
def validate_server_e(self):
|
||||
if not self.server_e.isEnabled():
|
||||
self.server_e.setStyleSheet("")
|
||||
self.server_e_valid.emit(True)
|
||||
return
|
||||
server = ServerAddr.from_str_with_inference(self.server_e.text())
|
||||
self.server_e.setStyleSheet("background-color: rgba(255, 0, 0, 0.2);" if not server else "")
|
||||
self.server_e_valid.emit(server is not None)
|
||||
|
||||
def update_from_config(self):
|
||||
auto_connect = self.config.NETWORK_AUTO_CONNECT
|
||||
one_server = self.config.NETWORK_ONESERVER
|
||||
|
||||
@@ -91,7 +91,10 @@ class WCServerConfig(WizardComponent):
|
||||
WizardComponent.__init__(self, parent, wizard, title=_('Server'))
|
||||
self.sw = ServerWidget(wizard._daemon.network, self)
|
||||
self.layout().addWidget(self.sw)
|
||||
self._valid = True
|
||||
self.sw.server_e_valid.connect(self.on_server_e_valid)
|
||||
|
||||
def on_server_e_valid(self, valid):
|
||||
self.valid = valid
|
||||
|
||||
def apply(self):
|
||||
self.wizard_data['autoconnect'] = self.sw.server_e.text().strip() == ''
|
||||
|
||||
@@ -826,7 +826,7 @@ class ServerConnectWizard(AbstractWizard):
|
||||
self.navmap = {
|
||||
'welcome': {
|
||||
'next': lambda d: 'proxy_config' if d['want_proxy'] else 'server_config',
|
||||
'accept': self.do_configure_autoconnect,
|
||||
'accept': lambda d: self.do_enable_autoconnect(d) if d['autoconnect'] else None,
|
||||
'last': lambda d: bool(d['autoconnect'] and not d['want_proxy'])
|
||||
},
|
||||
'proxy_config': {
|
||||
@@ -855,23 +855,27 @@ class ServerConnectWizard(AbstractWizard):
|
||||
def do_configure_server(self, wizard_data: dict):
|
||||
self._logger.debug(f'configuring server: {wizard_data!r}')
|
||||
net_params = self._daemon.network.get_parameters()
|
||||
server = ''
|
||||
server = None
|
||||
oneserver = wizard_data.get('one_server', False)
|
||||
if not wizard_data['autoconnect']:
|
||||
try:
|
||||
server = ServerAddr.from_str_with_inference(wizard_data['server'])
|
||||
if not server:
|
||||
raise Exception('failed to parse server %s' % wizard_data['server'])
|
||||
except Exception:
|
||||
return
|
||||
net_params = net_params._replace(server=server, auto_connect=wizard_data['autoconnect'], oneserver=oneserver)
|
||||
server = ServerAddr.from_str_with_inference(wizard_data.get('server', ''))
|
||||
if not server:
|
||||
self._logger.warn('failed to parse server %s' % wizard_data.get('server', ''))
|
||||
return # Network._start() will set autoconnect and default server
|
||||
net_params = net_params._replace(
|
||||
server=server or net_params.server,
|
||||
auto_connect=wizard_data['autoconnect'],
|
||||
oneserver=oneserver,
|
||||
)
|
||||
self._daemon.network.run_from_another_thread(self._daemon.network.set_parameters(net_params))
|
||||
|
||||
def do_configure_autoconnect(self, wizard_data: dict):
|
||||
self._logger.debug(f'configuring autoconnect: {wizard_data!r}')
|
||||
def do_enable_autoconnect(self, wizard_data: dict):
|
||||
# NETWORK_AUTO_CONNECT will only get explicitly set True, 'autoconnect': False means
|
||||
# the user requested manual server configuration
|
||||
self._logger.debug(f'enabling autoconnect: {wizard_data!r}')
|
||||
assert wizard_data.get('autoconnect'), wizard_data
|
||||
if self._daemon.config.cv.NETWORK_AUTO_CONNECT.is_modifiable():
|
||||
if wizard_data.get('autoconnect') is not None:
|
||||
self._daemon.config.NETWORK_AUTO_CONNECT = wizard_data.get('autoconnect')
|
||||
self._daemon.config.NETWORK_AUTO_CONNECT = True
|
||||
|
||||
def start(self, *, start_viewstate: WizardViewState = None) -> WizardViewState:
|
||||
self.reset()
|
||||
|
||||
@@ -81,7 +81,7 @@ class ServerConnectWizardTestCase(WizardTestCase):
|
||||
self.assertFalse(w.is_last_view(v_init.view, d))
|
||||
v = w.resolve_next(v_init.view, d)
|
||||
self.assertEqual('server_config', v.view)
|
||||
self.assertEqual(False, self.config.NETWORK_AUTO_CONNECT)
|
||||
self.assertFalse(self.config.cv.NETWORK_AUTO_CONNECT.is_set())
|
||||
|
||||
async def test_proxy(self):
|
||||
w = ServerConnectWizard(DaemonMock(self.config))
|
||||
@@ -110,7 +110,7 @@ class ServerConnectWizardTestCase(WizardTestCase):
|
||||
self.assertFalse(w.is_last_view(v_init.view, d))
|
||||
v = w.resolve_next(v_init.view, d)
|
||||
self.assertEqual('proxy_config', v.view)
|
||||
self.assertEqual(False, self.config.NETWORK_AUTO_CONNECT)
|
||||
self.assertFalse(self.config.cv.NETWORK_AUTO_CONNECT.is_set())
|
||||
d_proxy = {'enabled': False}
|
||||
d.update({'proxy': d_proxy})
|
||||
v = w.resolve_next(v.view, d)
|
||||
|
||||
Reference in New Issue
Block a user