From a757d5224499665f44d6a4f4ca8597208bfa3ddd Mon Sep 17 00:00:00 2001 From: Simon Quigley Date: Tue, 5 Dec 2023 18:22:56 -0600 Subject: [PATCH] =?UTF-8?q?Correct=20the=20logic=20for=20incorrect=20passw?= =?UTF-8?q?ords.=20Looks=20like=20spaghetti.=20=F0=9F=8D=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/installerprompt.cpp | 232 ++++++++++++++++++++-------------------- src/installerprompt.h | 19 ++-- src/installerprompt.ui | 152 +++++++++++++++----------- 3 files changed, 212 insertions(+), 191 deletions(-) diff --git a/src/installerprompt.cpp b/src/installerprompt.cpp index 57156b8..3fad66a 100644 --- a/src/installerprompt.cpp +++ b/src/installerprompt.cpp @@ -12,7 +12,6 @@ #include #include #include -#include #include #include "installerprompt.h" #include "./ui_installerprompt.h" @@ -22,6 +21,9 @@ InstallerPrompt::InstallerPrompt(QWidget *parent) , ui(new Ui::InstallerPrompt) { ui->setupUi(this); + // Hide the Incorrect Password text + ui->incorrectPassword->setVisible(false); + // Set the background image and scale it QPixmap bg(":/background"); if (bg.isNull()) { @@ -78,6 +80,8 @@ void InstallerPrompt::updateConnectionStatus() { switch (status) { case NetworkManager::Status::Disconnected: + case NetworkManager::ConnectedLinkLocal: + case NetworkManager::Asleep: statusText = tr("Not Connected"); statusIndicator = " " + statusText; break; @@ -95,6 +99,7 @@ void InstallerPrompt::updateConnectionStatus() { statusIndicator = "🟡 " + statusText; break; default: + qDebug() << "Unknown status:" << status; statusText = tr("Unknown Status"); statusIndicator = " " + statusText; } @@ -120,162 +125,154 @@ void InstallerPrompt::updateConnectionStatus() { void InstallerPrompt::handleWiFiConnectionChange(NetworkManager::Device::State newstate, NetworkManager::Device::State oldstate, NetworkManager::Device::StateChangeReason reason) { - if (reason == NetworkManager::Device::NoSecretsReason) { + QMutexLocker locker(&wifiChangeMutex); + if (reason == NetworkManager::Device::NoSecretsReason && !wifiWrongHandling) { + wifiWrongHandling = true; + qDebug() << wifiSSID; + foreach (const NetworkManager::Connection::Ptr &connection, NetworkManager::listConnections()) { if (connection->settings()->connectionType() == NetworkManager::ConnectionSettings::Wireless) { auto wirelessSetting = connection->settings()->setting(NetworkManager::Setting::Wireless).dynamicCast(); - if (wirelessSetting && wirelessSetting->ssid() == ui->networkComboBox->currentText()) { - qDebug() << "Wiping connection with wrong password: " << ui->networkComboBox->currentText(); + if (wirelessSetting && wirelessSetting->ssid() == wifiSSID) { + qDebug() << "Wiping connection with wrong password: " << wifiSSID; + // Show the Incorrect Password text + ui->incorrectPassword->setVisible(true); QDBusPendingReply removeReply = connection->remove(); removeReply.waitForFinished(); - handleWifiConnection(ui->networkComboBox->currentText(), true); } } } + wifiWrongHandling = false; } } -void InstallerPrompt::handleWifiConnection(const QString &ssid, bool recoverFromWrongPassword) { - ui->networkComboBox->setEnabled(false); - qDebug() << "Attempting to find connection for SSID:" << ssid; - if (!recoverFromWrongPassword) { - foreach (const NetworkManager::Connection::Ptr &connection, NetworkManager::listConnections()) { - if (connection->settings()->connectionType() == NetworkManager::ConnectionSettings::Wireless) { - auto wirelessSetting = connection->settings()->setting(NetworkManager::Setting::Wireless).dynamicCast(); - if (wirelessSetting && wirelessSetting->ssid() == ssid) { - qDebug() << "Attempting to use existing connection:" << ssid; - NetworkManager::activateConnection(connection->path(), wifiDevice->uni(), QString()); - qDebug() << "Successfully connected:" << ssid; - ui->networkComboBox->setEnabled(true); - return; - } +NetworkManager::Connection::Ptr InstallerPrompt::findConnectionBySsid(const QString &ssid) { + foreach (const NetworkManager::Connection::Ptr &connection, NetworkManager::listConnections()) { + if (connection->settings()->connectionType() == NetworkManager::ConnectionSettings::Wireless) { + auto wirelessSetting = connection->settings()->setting(NetworkManager::Setting::Wireless).dynamicCast(); + if (wirelessSetting && wirelessSetting->ssid() == ssid) { + return connection; } } } + return NetworkManager::Connection::Ptr(); // Return null pointer if not found +} + +QString InstallerPrompt::promptForWifiPassword(const QString &ssid, bool isWrongPassword) { + QDialog passwordDialog(this); + passwordDialog.setModal(true); + passwordDialog.setWindowTitle(tr("Wi-Fi Password Required")); + passwordDialog.setWindowIcon(QIcon::fromTheme("network-wireless")); + passwordDialog.setStyleSheet("QLabel { color: black; } "); + passwordDialog.setMinimumWidth(250); + passwordDialog.setMinimumHeight(120); + passwordDialog.setMaximumWidth(5000); + passwordDialog.setMaximumHeight(500); + + QVBoxLayout layout; + QLabel passwordLabel(tr("Enter password for \"%1\":").arg(ssid), &passwordDialog); + QLineEdit passwordLineEdit(&passwordDialog); + QPushButton passwordButton(tr("Connect"), &passwordDialog); + + passwordLineEdit.setEchoMode(QLineEdit::Password); + layout.addWidget(&passwordLabel); + layout.addWidget(&passwordLineEdit); + layout.addWidget(&passwordButton); + + passwordDialog.setLayout(&layout); + + // Connect with a lambda function for inline validation + connect(&passwordLineEdit, &QLineEdit::textChanged, this, [&passwordLineEdit](const QString &text) { + int minLength = 8; + int maxLength = 64; + bool isValid = text.length() >= minLength && text.length() <= maxLength; + passwordLineEdit.setStyleSheet(isValid ? "" : "border: 1px solid red;"); + }); - QMap fullSettings = createSettingsBySSID(ssid); - NMVariantMapMap nmMap; + connect(&passwordButton, &QPushButton::clicked, &passwordDialog, &QDialog::accept); - for (const auto &key : fullSettings.keys()) { - nmMap[key] = fullSettings[key].toMap(); + if (passwordDialog.exec() == QDialog::Accepted) { + return passwordLineEdit.text(); } - NetworkManager::ConnectionSettings::Ptr newConnectionSettings(new NetworkManager::ConnectionSettings(NetworkManager::ConnectionSettings::Wireless)); - newConnectionSettings->fromMap(nmMap); - QVariantMap wirelessSecurity = fullSettings.value("802-11-wireless-security").toMap(); + return QString(); +} - //bool isOpenNetwork = wirelessSecurity.isEmpty() || wirelessSecurity.value("key-mgmt").toString().isEmpty(); - //if (isOpenNetwork && wifiDevice && wifiDevice->isValid() && connection) { - // qDebug() << "Attempting to connect to open network: " << ssid; - // NetworkManager::activateConnection(connection->path(), wifiDevice->uni(), QString()); - // return; - //} +void InstallerPrompt::handleWifiConnection(const QString &ssid, bool recoverFromWrongPassword) { + ui->incorrectPassword->setVisible(false); + ui->networkComboBox->setEnabled(false); + wifiSSID = ssid; + qDebug() << "Attempting to find connection for SSID:" << ssid; - // If the network is secured, display the password dialog - QDialog passwordDialog(this); - QVBoxLayout layout(&passwordDialog); - QLabel label(&passwordDialog); - if (!recoverFromWrongPassword) { - label.setText(tr("Enter Wi-Fi Password for %1:").arg(ssid)); - label.setStyleSheet("color: black"); - } else { - label.setText(tr("Wrong Wi-Fi password for %1. Try again:").arg(ssid)); - label.setStyleSheet("color: red"); + // Check for existing connection + NetworkManager::Connection::Ptr connection = findConnectionBySsid(ssid); + if (connection && !recoverFromWrongPassword) { + qDebug() << "Using existing connection for:" << ssid; + NetworkManager::activateConnection(connection->path(), wifiDevice->uni(), QString()); + ui->networkComboBox->setEnabled(true); + return; } - QLineEdit lineEdit(&passwordDialog); - QPushButton button(tr("Connect"), &passwordDialog); - lineEdit.setEchoMode(QLineEdit::Password); - layout.addWidget(&label); - layout.addWidget(&lineEdit); - layout.addWidget(&button); + // Prompt for Wi-Fi password + QString password = promptForWifiPassword(ssid); + if (password.isEmpty()) { + ui->networkComboBox->setEnabled(true); + return; + } - connect(&button, &QPushButton::clicked, &passwordDialog, &QDialog::accept); + // Create new Wi-Fi connection + NMVariantMapMap settings = createSettingsBySSID(ssid); + if (settings.isEmpty()) { + QMessageBox::warning(this, tr("Error"), tr("Failed to create Wi-Fi settings.")); + ui->networkComboBox->setEnabled(true); + return; + } - for (int attempts = 0; attempts < 3; ++attempts) { - if (passwordDialog.exec() == QDialog::Rejected) { - ui->networkComboBox->setEnabled(true); - return; - } - QString password = lineEdit.text(); - if (wifiDevice && wifiDevice->isValid()) { - // Update the wireless security settings in the map - wirelessSecurity["key-mgmt"] = "wpa-psk"; - wirelessSecurity["psk"] = password; - fullSettings["802-11-wireless-security"] = wirelessSecurity; - - // Convert QMap to NMVariantMapMap - NMVariantMapMap nmMap; - for (const auto &key : fullSettings.keys()) { - nmMap[key] = fullSettings[key].toMap(); - } + // Update the wireless security settings + QVariantMap wirelessSecurity; + wirelessSecurity["key-mgmt"] = "wpa-psk"; + wirelessSecurity["psk"] = password; + settings["802-11-wireless-security"] = wirelessSecurity; + + // Add the new connection + QDBusPendingReply reply = NetworkManager::addConnection(settings); + reply.waitForFinished(); + if (reply.isError()) { + QMessageBox::warning(this, tr("Error"), tr("Failed to add Wi-Fi connection.")); + ui->networkComboBox->setEnabled(true); + return; + } - // Update the connection settings - qDebug() << "Saving the connection..."; - QDBusObjectPath path; - NetworkManager::ConnectionSettings::Ptr newConnectionSettings(new NetworkManager::ConnectionSettings(NetworkManager::ConnectionSettings::Wireless)); - newConnectionSettings->fromMap(nmMap); - QDBusPendingReply addreply = NetworkManager::addConnection(nmMap); - addreply.waitForFinished(); - if (addreply.isError()) { - qDebug() << nmMap; - qDebug() << "Unable to save the connection:" << addreply.error().message(); - } else { - path = addreply.value(); - qDebug() << "Added connection path:" << path.path(); - } + // Activate the new connection + QDBusObjectPath path = reply.value(); + NetworkManager::activateConnection(path.path(), wifiDevice->uni(), QString()); + ui->networkComboBox->setEnabled(true); +} - NetworkManager::Connection::Ptr connection = NetworkManager::findConnection(path.path()); - if (!connection) { - qDebug() << "Unable to retrieve the connection after saving:" << addreply.error().message(); - } +NMVariantMapMap InstallerPrompt::createSettingsBySSID(const QString &ssid) { + NMVariantMapMap convertedSettings; - QDBusPendingReply reply = NetworkManager::activateConnection(connection->path(), wifiDevice->uni(), QString()); - reply.waitForFinished(); - if (reply.isError()) { - qDebug() << "Unable to activate the connection:" << addreply.error().message(); - QMessageBox::warning(this, tr("Connection Failed"), tr("Unable to connect to the network.")); - ui->networkComboBox->setEnabled(true); - return; - } else { - NetworkManager::reloadConnections(); - qDebug() << "Successfully connected:" << ssid; - // ui->networkComboBox->setEnabled(true); !!! We don't run this here since we actually *want* the box to remain locked right now - return; - } - } + if (!wifiDevice) { + qWarning() << "Wi-Fi device not found. Unable to set interface name."; + return convertedSettings; } -} -QMap InstallerPrompt::createSettingsBySSID(const QString &ssid) { - // Create new connection settings NetworkManager::ConnectionSettings::Ptr newConnectionSettings(new NetworkManager::ConnectionSettings(NetworkManager::ConnectionSettings::Wireless)); newConnectionSettings->setId(ssid); newConnectionSettings->setUuid(NetworkManager::ConnectionSettings::createNewUuid()); - - // Set interface name from wifiDevice - if (wifiDevice) { - newConnectionSettings->setInterfaceName(wifiDevice->interfaceName()); - } else { - qWarning() << "Wi-Fi device not found. Unable to set interface name."; - return QMap(); - } + newConnectionSettings->setInterfaceName(wifiDevice->interfaceName()); // Configure wireless settings QVariantMap wirelessSetting; wirelessSetting.insert("ssid", ssid.toUtf8()); + convertedSettings.insert("802-11-wireless", wirelessSetting); - // Configure wireless security settings - NetworkManager::WirelessSecuritySetting::Ptr wirelessSecuritySetting = newConnectionSettings->setting(NetworkManager::Setting::WirelessSecurity).staticCast(); - wirelessSecuritySetting->setKeyMgmt(NetworkManager::WirelessSecuritySetting::WpaPsk); - - // Convert settings to QVariantMap - QMap convertedSettings; + // Convert other settings const auto settingsMap = newConnectionSettings->toMap(); for (const auto &key : settingsMap.keys()) { - convertedSettings[key] = QVariant::fromValue(settingsMap[key]); + QVariant value = settingsMap.value(key); + convertedSettings.insert(key, value.toMap()); } - convertedSettings.insert("802-11-wireless", wirelessSetting); return convertedSettings; } @@ -334,7 +331,6 @@ void InstallerPrompt::refreshNetworkList() { } // Update the main map and combo box only after the new list is ready - wifiNetworkMap.swap(tempWifiNetworkMap); ui->networkComboBox->clear(); ui->networkComboBox->addItems(ssidList); diff --git a/src/installerprompt.h b/src/installerprompt.h index ca46ae4..9e17b87 100644 --- a/src/installerprompt.h +++ b/src/installerprompt.h @@ -7,16 +7,12 @@ #include #include #include +#include +#include #include #include #include -namespace NetworkManager { - class Device; - class WirelessDevice; - class WirelessNetwork; -} - namespace Ui { class InstallerPrompt; } class InstallerPrompt : public QMainWindow { @@ -39,14 +35,19 @@ private: Ui::InstallerPrompt *ui; QProcess *process; NetworkManager::WirelessDevice::Ptr wifiDevice; - QMap wifiNetworkMap; + QString wifiSSID; + QMutex wifiChangeMutex; + NetworkManager::Connection::Ptr findConnectionBySsid(const QString &ssid); + bool wifiWrongHandling = false; + QLineEdit *passwordLineEdit; void handleWifiConnection(const QString &ssid, bool recoverFromWrongPassword = false); + QString promptForWifiPassword(const QString &ssid, bool isWrongPassword = false); + void connectToWifi(const QString &ssid, const QString &password, bool recoverFromWrongPassword = false); void initLanguageComboBox(); QStringList getAvailableLanguages() const; void showWifiOptions(); - NetworkManager::Connection::Ptr findConnectionBySsid(const QString &ssid); - QMap createSettingsBySSID(const QString &ssid); + NMVariantMapMap createSettingsBySSID(const QString &ssid); }; #endif // INSTALLERPROMPT_H diff --git a/src/installerprompt.ui b/src/installerprompt.ui index 814efef..6f97c9d 100644 --- a/src/installerprompt.ui +++ b/src/installerprompt.ui @@ -59,7 +59,10 @@ QLabel#logoLabel { image: url(:/logo); background-color: transparent; } - + +QLabel#incorrectPassword { + color: red; +} @@ -128,6 +131,7 @@ QLabel#logoLabel { Ubuntu + 50 false false @@ -200,6 +204,7 @@ QLabel#logoLabel { 18 + 75 true @@ -258,80 +263,61 @@ QLabel#logoLabel { - - - - - Qt::Horizontal + + + + + + 150 + 65 + - + - 40 - 20 + 150 + 65 - - - - - 18 + 75 true - Select a Wi-Fi Network: + Connect - - - - - 352 - 50 - - - - - 400 - 50 - - + + - 16 + 75 + true + + (For advanced network configuration, select "Try Lubuntu") + - - - - - 100 - 65 - - - - - 16777215 - 65 - - + + + 18 + 75 true - Connect + Select a Wi-Fi Network: - - + + Qt::Horizontal @@ -343,12 +329,8 @@ QLabel#logoLabel { - - - - - - + + Qt::Horizontal @@ -360,20 +342,21 @@ QLabel#logoLabel { - - - - - true - + + + + Qt::Horizontal - - (For advanced network configuration, select "Try Lubuntu") + + + 40 + 20 + - + - - + + Qt::Horizontal @@ -385,6 +368,44 @@ QLabel#logoLabel { + + + + + 352 + 50 + + + + + 550 + 50 + + + + + 16 + + + + + + + + true + + + + 16 + 75 + true + + + + You entered an incorrect password. Please try again. + + + @@ -459,6 +480,7 @@ QLabel#logoLabel { Ubuntu 24 + 75 true @@ -535,6 +557,7 @@ QToolTip { Ubuntu 24 + 75 true @@ -677,6 +700,7 @@ QToolTip { 24 + 75 true