File indexing completed on 2024-04-14 15:39:57

0001 /*
0002     SPDX-FileCopyrightText: 2013 Lukas Tinkl <ltinkl@redhat.com>
0003     SPDX-FileCopyrightText: 2013 Daniel Nicoletti <dantti12@gmail.com>
0004 
0005     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0006 */
0007 
0008 #include "passworddialog.h"
0009 #include "plasma_nm_kded.h"
0010 #include "ui_passworddialog.h"
0011 #include "uiutils.h"
0012 
0013 #include <vpnuiplugin.h>
0014 
0015 #include <NetworkManagerQt/Utils>
0016 #include <NetworkManagerQt/VpnSetting>
0017 #include <NetworkManagerQt/WirelessSetting>
0018 
0019 #include <KLocalizedString>
0020 
0021 #include <QIcon>
0022 #include <QPushButton>
0023 
0024 using namespace NetworkManager;
0025 
0026 PasswordDialog::PasswordDialog(const NetworkManager::ConnectionSettings::Ptr &connectionSettings,
0027                                SecretAgent::GetSecretsFlags flags,
0028                                const QString &setting_name,
0029                                const QStringList &hints,
0030                                QWidget *parent)
0031     : QDialog(parent)
0032     , m_settingName(setting_name)
0033     , m_connectionSettings(connectionSettings)
0034     , m_error(SecretAgent::NoSecrets)
0035     , m_flags(flags)
0036     , m_hints(hints)
0037 {
0038     setWindowIcon(QIcon::fromTheme(QStringLiteral("dialog-password")));
0039 
0040     initializeUi();
0041 }
0042 
0043 PasswordDialog::~PasswordDialog()
0044 {
0045     delete m_ui;
0046 }
0047 
0048 void PasswordDialog::initializeUi()
0049 {
0050     m_ui = new Ui::PasswordDialog;
0051     m_ui->setupUi(this);
0052     // TODO fix this for high DPI
0053     m_ui->labelIcon->setPixmap(QIcon::fromTheme(QStringLiteral("dialog-password")).pixmap(64));
0054     m_ui->labelHeadline->setText(i18n("Authenticate %1", m_connectionSettings->id()));
0055 
0056     connect(m_ui->buttonBox, &QDialogButtonBox::accepted, this, &PasswordDialog::accept);
0057     connect(m_ui->buttonBox, &QDialogButtonBox::rejected, this, &PasswordDialog::reject);
0058     connect(m_ui->password, &PasswordField::textChanged, [this](const QString &text) {
0059         if (m_connectionSettings->connectionType() == NetworkManager::ConnectionSettings::Wireless) {
0060             NetworkManager::WirelessSecuritySetting::Ptr wirelessSecuritySetting =
0061                 m_connectionSettings->setting(NetworkManager::Setting::WirelessSecurity).staticCast<NetworkManager::WirelessSecuritySetting>();
0062             bool valid = true;
0063 
0064             if (wirelessSecuritySetting) {
0065                 switch (wirelessSecuritySetting->keyMgmt()) {
0066                 case NetworkManager::WirelessSecuritySetting::WpaPsk:
0067                     valid = wpaPskIsValid(text);
0068                     break;
0069                 case NetworkManager::WirelessSecuritySetting::Wep:
0070                     valid = wepKeyIsValid(text, wirelessSecuritySetting->wepKeyType());
0071                     break;
0072                 default:
0073                     break;
0074                 }
0075             }
0076 
0077             // disable button if key is not valid
0078             m_ui->buttonBox->button(QDialogButtonBox::Ok)->setDisabled(!valid);
0079         }
0080     });
0081 
0082     if (m_connectionSettings->connectionType() != NetworkManager::ConnectionSettings::Vpn) {
0083         NetworkManager::Setting::Ptr setting = m_connectionSettings->setting(m_settingName);
0084         m_neededSecrets = setting->needSecrets(m_flags & SecretAgent::RequestNew);
0085 
0086         if (m_neededSecrets.isEmpty()) {
0087             qCWarning(PLASMA_NM_KDED_LOG) << "list of secrets is empty!!!";
0088             m_hasError = true;
0089             m_error = SecretAgent::InternalError;
0090             m_errorMessage = QLatin1String("No secrets were requested");
0091             return;
0092         }
0093 
0094         WirelessSetting::Ptr wifi = m_connectionSettings->setting(Setting::Wireless).dynamicCast<WirelessSetting>();
0095         Setting::SettingType connectionType = setting->type();
0096         if (wifi && (connectionType == Setting::WirelessSecurity || connectionType == Setting::Security8021x)) {
0097             const QString ssid = QString::fromUtf8(wifi->ssid());
0098             m_ui->labelText->setText(i18n("Provide the password for the wireless network '%1':", ssid));
0099         } else {
0100             m_ui->labelText->setText(i18n("Provide the password for the connection '%1':", m_connectionSettings->id()));
0101         }
0102 
0103         QString connectionLabel;
0104         UiUtils::iconAndTitleForConnectionSettingsType(m_connectionSettings->connectionType(), connectionLabel);
0105         setFocusProxy(m_ui->password);
0106         setWindowTitle(i18n("%1 password dialog", connectionLabel));
0107     } else {
0108         NetworkManager::VpnSetting::Ptr vpnSetting = m_connectionSettings->setting(Setting::Vpn).dynamicCast<VpnSetting>();
0109         if (!vpnSetting) {
0110             qCWarning(PLASMA_NM_KDED_LOG) << "Missing VPN setting!";
0111             m_hasError = true;
0112             m_error = SecretAgent::InternalError;
0113             m_errorMessage = QLatin1String("VPN settings are missing");
0114         } else {
0115             const QString serviceType = vpnSetting->serviceType();
0116             const auto result = VpnUiPlugin::loadPluginForType(this, serviceType);
0117 
0118             if (result) {
0119                 VpnUiPlugin *vpnUiPlugin = result.plugin;
0120                 const QString shortName = serviceType.section('.', -1);
0121                 NMStringMap data = vpnSetting->data();
0122                 m_vpnWidget = vpnUiPlugin->askUser(vpnSetting, m_hints, this);
0123                 auto layout = new QVBoxLayout();
0124                 layout->addWidget(m_vpnWidget);
0125                 m_ui->vpnWidget->setLayout(layout);
0126                 m_ui->labelText->setText(i18n("Provide the secrets for the VPN connection '%1':", m_connectionSettings->id()));
0127                 setWindowTitle(i18n("VPN secrets (%1) dialog", shortName));
0128 
0129                 // Hide generic password field and OK button in case of openconnect dialog
0130                 m_ui->labelPass->setVisible(false);
0131                 m_ui->password->setVisible(false);
0132                 if (shortName == QLatin1String("openconnect")) {
0133                     QAbstractButton *button = m_ui->buttonBox->button(QDialogButtonBox::Ok);
0134                     m_ui->buttonBox->removeButton(button);
0135                 }
0136 
0137                 setFocusProxy(m_vpnWidget);
0138                 m_vpnWidget->setFocus(Qt::OtherFocusReason);
0139             } else {
0140                 qCWarning(PLASMA_NM_KDED_LOG) << "Could not load VPN UI plugin" << result.errorText;
0141                 m_hasError = true;
0142                 m_error = SecretAgent::InternalError;
0143                 m_errorMessage = result.errorString;
0144             }
0145         }
0146     }
0147 
0148     // Workaround to force m_ui->password to get focus.
0149     focusNextChild();
0150 }
0151 
0152 bool PasswordDialog::hasError() const
0153 {
0154     return m_hasError;
0155 }
0156 
0157 SecretAgent::Error PasswordDialog::error() const
0158 {
0159     return m_error;
0160 }
0161 
0162 QString PasswordDialog::errorMessage() const
0163 {
0164     return m_errorMessage;
0165 }
0166 
0167 NMVariantMapMap PasswordDialog::secrets() const
0168 {
0169     NMVariantMapMap ret = m_connectionSettings->toMap();
0170     QVariantMap result;
0171     if (m_vpnWidget) {
0172         result = m_vpnWidget->setting();
0173     } else if (!m_ui->password->text().isEmpty() && !m_neededSecrets.isEmpty()) {
0174         result.insert(m_neededSecrets.first(), m_ui->password->text());
0175     }
0176 
0177     ret.insert(m_settingName, result);
0178 
0179     return ret;
0180 }