passworddialog.cpp 8.51 KB
Newer Older
Jan Grulich's avatar
Jan Grulich committed
1
2
/*
    Copyright 2013 Lukas Tinkl <ltinkl@redhat.com>
3
    Copyright 2013 by Daniel Nicoletti <dantti12@gmail.com>
Jan Grulich's avatar
Jan Grulich committed
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) version 3, or any
    later version accepted by the membership of KDE e.V. (or its
    successor approved by the membership of KDE e.V.), which shall
    act as a proxy defined in Section 6 of version 3 of the license.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library.  If not, see <http://www.gnu.org/licenses/>.
*/

22
#include "debug.h"
23
#include "passworddialog.h"
24
#include "ui_passworddialog.h"
Jan Grulich's avatar
Jan Grulich committed
25
#include "uiutils.h"
26

27
28
#include <vpnuiplugin.h>

29
30
#include <NetworkManagerQt/WirelessSetting>
#include <NetworkManagerQt/VpnSetting>
Oleg Solovyov's avatar
Oleg Solovyov committed
31
#include <NetworkManagerQt/Utils>
32
33

#include <KServiceTypeTrader>
34
#include <KLocalizedString>
35
36
37
#include <KIconLoader>

#include <QIcon>
Jan Grulich's avatar
Jan Grulich committed
38
#include <QPushButton>
39

40
41
using namespace NetworkManager;

Jan Grulich's avatar
Jan Grulich committed
42
PasswordDialog::PasswordDialog(const NetworkManager::ConnectionSettings::Ptr &connectionSettings, SecretAgent::GetSecretsFlags flags,
43
                               const QString &setting_name, const QStringList &hints, QWidget *parent) :
44
    QDialog(parent),
Friedrich W. H. Kossebau's avatar
Friedrich W. H. Kossebau committed
45
    m_ui(nullptr),
46
    m_hasError(false),
Jan Grulich's avatar
Jan Grulich committed
47
48
49
50
    m_settingName(setting_name),
    m_connectionSettings(connectionSettings),
    m_error(SecretAgent::NoSecrets),
    m_flags(flags),
Friedrich W. H. Kossebau's avatar
Friedrich W. H. Kossebau committed
51
    m_vpnWidget(nullptr)
52
    m_hints(hints)
53
{
Nick Shaforostoff's avatar
Nick Shaforostoff committed
54
    setWindowIcon(QIcon::fromTheme(QStringLiteral("dialog-password")));
Jan Grulich's avatar
Jan Grulich committed
55
56

    initializeUi();
57
58
59
60
}

PasswordDialog::~PasswordDialog()
{
Jan Grulich's avatar
Jan Grulich committed
61
    delete m_ui;
62
63
}

Jan Grulich's avatar
Jan Grulich committed
64
void PasswordDialog::initializeUi()
65
{
Jan Grulich's avatar
Jan Grulich committed
66
67
    m_ui = new Ui::PasswordDialog;
    m_ui->setupUi(this);
68
    // TODO fix this for high DPI
Jan Grulich's avatar
Jan Grulich committed
69
70
    m_ui->labelIcon->setPixmap(QIcon::fromTheme(QStringLiteral("dialog-password")).pixmap(KIconLoader::SizeHuge));
    m_ui->labelHeadline->setText(i18n("Authenticate %1", m_connectionSettings->id()));
71

Jan Grulich's avatar
Jan Grulich committed
72
73
    connect(m_ui->buttonBox, &QDialogButtonBox::accepted, this, &PasswordDialog::accept);
    connect(m_ui->buttonBox, &QDialogButtonBox::rejected, this, &PasswordDialog::reject);
Oleg Solovyov's avatar
Oleg Solovyov committed
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
    connect(m_ui->password, &PasswordField::textChanged, [this](const QString &text){
        if (m_connectionSettings->connectionType() == NetworkManager::ConnectionSettings::Wireless) {
            NetworkManager::WirelessSecuritySetting::Ptr wirelessSecuritySetting =
                    m_connectionSettings->setting(NetworkManager::Setting::WirelessSecurity).staticCast<NetworkManager::WirelessSecuritySetting>();
            bool valid = true;

            if (wirelessSecuritySetting) {
                switch (wirelessSecuritySetting->keyMgmt()) {
                case NetworkManager::WirelessSecuritySetting::WpaPsk:
                    valid = wpaPskIsValid(text);
                    break;
                case NetworkManager::WirelessSecuritySetting::Wep:
                    valid = wepKeyIsValid(text, wirelessSecuritySetting->wepKeyType());
                    break;
                default:
                    break;
                }
            }

            // disable button if key is not valid
            m_ui->buttonBox->button(QDialogButtonBox::Ok)->setDisabled(!valid);
        }
    });
97

Jan Grulich's avatar
Jan Grulich committed
98
99
100
    if (m_connectionSettings->connectionType() != NetworkManager::ConnectionSettings::Vpn) {
        NetworkManager::Setting::Ptr setting = m_connectionSettings->setting(m_settingName);
        m_neededSecrets = setting->needSecrets(m_flags & SecretAgent::RequestNew);
Lukáš Tinkl's avatar
Lukáš Tinkl committed
101

Jan Grulich's avatar
Jan Grulich committed
102
103
104
105
106
107
108
        if (m_neededSecrets.isEmpty()) {
            qCWarning(PLASMA_NM) << "list of secrets is empty!!!";
            m_hasError = true;
            m_error = SecretAgent::InternalError;
            m_errorMessage = QLatin1String("No secrets were requested");
            return;
        }
109

Jan Grulich's avatar
Jan Grulich committed
110
111
112
113
        WirelessSetting::Ptr wifi = m_connectionSettings->setting(Setting::Wireless).dynamicCast<WirelessSetting>();
        Setting::SettingType connectionType = setting->type();
        if (wifi && (connectionType == Setting::WirelessSecurity || connectionType == Setting::Security8021x)) {
            const QString ssid = QString::fromUtf8(wifi->ssid());
114
            m_ui->labelText->setText(i18n("Provide the password for the wireless network '%1':", ssid));
115
        } else {
116
            m_ui->labelText->setText(i18n("Provide the password for the connection '%1':", m_connectionSettings->id()));
Jan Grulich's avatar
Jan Grulich committed
117
118
119
120
        }

        QString connectionLabel;
        UiUtils::iconAndTitleForConnectionSettingsType(m_connectionSettings->connectionType(), connectionLabel);
121
        setFocusProxy(m_ui->password);
Jan Grulich's avatar
Jan Grulich committed
122
123
124
125
126
        setWindowTitle(i18n("%1 password dialog", connectionLabel));
    } else {
        NetworkManager::VpnSetting::Ptr vpnSetting = m_connectionSettings->setting(Setting::Vpn).dynamicCast<VpnSetting>();
        if (!vpnSetting) {
            qCWarning(PLASMA_NM) << "Missing VPN setting!";
127
128
            m_hasError = true;
            m_error = SecretAgent::InternalError;
Jan Grulich's avatar
Jan Grulich committed
129
130
131
132
133
134
135
136
137
138
            m_errorMessage = QLatin1String("VPN settings are missing");
        } else {
            VpnUiPlugin *vpnUiPlugin;
            QString error;
            const QString serviceType = vpnSetting->serviceType();
            vpnUiPlugin = KServiceTypeTrader::createInstanceFromQuery<VpnUiPlugin>(QLatin1String("PlasmaNetworkManagement/VpnUiPlugin"),
                                                                                   QString::fromLatin1("[X-NetworkManager-Services]=='%1'").arg(serviceType),
                                                                                   this, QVariantList(), &error);
            if (vpnUiPlugin && error.isEmpty()) {
                const QString shortName = serviceType.section('.', -1);
139
140
141
142
143
144
145
                NMStringMap data = vpnSetting->data();
                // If we have hints, make the user have them through the widget
                if (!m_hints.isEmpty() && m_hints.size() == 2) {
                    data.insert("hint", m_hints[0]);
                    data.insert("hint-msg", m_hints[1]);
                    vpnSetting->setData(data);
                }
Jan Grulich's avatar
Jan Grulich committed
146
147
148
149
                m_vpnWidget = vpnUiPlugin->askUser(vpnSetting, this);
                QVBoxLayout *layout = new QVBoxLayout();
                layout->addWidget(m_vpnWidget);
                m_ui->vpnWidget->setLayout(layout);
150
                m_ui->labelText->setText(i18n("Provide the secrets for the VPN connection '%1':", m_connectionSettings->id()));
Jan Grulich's avatar
Jan Grulich committed
151
152
153
154
155
156
157
158
159
                setWindowTitle(i18n("VPN secrets (%1) dialog", shortName));

                // Hide generic password field and OK button in case of openconnect dialog
                m_ui->labelPass->setVisible(false);
                m_ui->password->setVisible(false);
                if (shortName == QLatin1String("openconnect")) {
                    QAbstractButton *button = m_ui->buttonBox->button(QDialogButtonBox::Ok);
                    m_ui->buttonBox->removeButton(button);
                }
160
161
162

                setFocusProxy(m_vpnWidget);
                m_vpnWidget->setFocus(Qt::OtherFocusReason);
163
164
165
166
167
168
169

                // Delete hins from vpnSetting
                if (!m_hints.isEmpty()) {
                    data.remove("hint");
                    data.remove("hint-msg");
                    vpnSetting->setData(data);
                }
Jan Grulich's avatar
Jan Grulich committed
170
171
172
173
174
175
            } else {
                qCWarning(PLASMA_NM) << error << ", serviceType == " << serviceType;
                m_hasError = true;
                m_error = SecretAgent::InternalError;
                m_errorMessage = error;
            }
176
177
        }
    }
178
179
180

    // Workaround to force m_ui->password to get focus.
    focusNextChild();
181
182
}

183
bool PasswordDialog::hasError() const
184
{
185
186
187
188
189
190
191
    return m_hasError;
}

SecretAgent::Error PasswordDialog::error() const
{
    return m_error;
}
192

193
194
195
196
197
198
199
QString PasswordDialog::errorMessage() const
{
    return m_errorMessage;
}

NMVariantMapMap PasswordDialog::secrets() const
{
Jan Grulich's avatar
Jan Grulich committed
200
    NMVariantMapMap ret = m_connectionSettings->toMap();
201
    QVariantMap result;
Jan Grulich's avatar
Jan Grulich committed
202
203
204
205
    if (m_vpnWidget) {
        result = m_vpnWidget->setting();
    } else if (!m_ui->password->text().isEmpty() && !m_neededSecrets.isEmpty()) {
        result.insert(m_neededSecrets.first(), m_ui->password->text());
206
207
208
    }

    ret.insert(m_settingName, result);
209

210
    return ret;
211
}