1 /*
2 This file is part of the KDE project
3 SPDX-FileCopyrightText: 2013 Valentin Rusu <kde@rusu.info>
4
5 SPDX-License-Identifier: LGPL-2.0-only
6 */
7
8 #include "knewwalletdialog.h"
9 #include "kwalletd_debug.h"
10 #include <KLocalizedString>
11 #include <KMessageBox>
12 #include <QTableWidget>
13 #include <QTableWidgetItem>
14 #include <gpgme++/context.h>
15 #include <gpgme++/key.h>
16 #include <gpgme++/keylistresult.h>
17
18 Q_DECLARE_METATYPE(GpgME::Key)
19
20 namespace KWallet
21 {
KNewWalletDialog(const QString & appName,const QString & walletName,QWidget * parent)22 KNewWalletDialog::KNewWalletDialog(const QString &appName, const QString &walletName, QWidget *parent)
23 : QWizard(parent)
24 {
25 setOption(HaveFinishButtonOnEarlyPages);
26 _intro = new KNewWalletDialogIntro(appName, walletName, this);
27 _introId = addPage(_intro);
28
29 _gpg = new KNewWalletDialogGpg(appName, walletName, this);
30 _gpgId = addPage(_gpg);
31 }
32
isBlowfish() const33 bool KNewWalletDialog::isBlowfish() const
34 {
35 return _intro->isBlowfish();
36 }
37
gpgKey() const38 GpgME::Key KNewWalletDialog::gpgKey() const
39 {
40 QVariant varKey = field(QStringLiteral("key"));
41 return varKey.value<GpgME::Key>();
42 }
43
KNewWalletDialogIntro(const QString & appName,const QString & walletName,QWidget * parent)44 KNewWalletDialogIntro::KNewWalletDialogIntro(const QString &appName, const QString &walletName, QWidget *parent)
45 : QWizardPage(parent)
46 {
47 _ui.setupUi(this);
48 if (appName.isEmpty()) {
49 _ui.labelIntro->setText(
50 i18n("<qt>KDE has requested to create a new wallet named '<b>%1</b>'. This is used to store sensitive data in a secure fashion. Please choose the "
51 "new wallet's type below or click cancel to deny the application's request.</qt>",
52 walletName.toHtmlEscaped()));
53 } else {
54 _ui.labelIntro->setText(
55 i18n("<qt>The application '<b>%1</b>' has requested to create a new wallet named '<b>%2</b>'. This is used to store sensitive data in a secure "
56 "fashion. Please choose the new wallet's type below or click cancel to deny the application's request.</qt>",
57 appName.toHtmlEscaped(),
58 walletName.toHtmlEscaped()));
59 }
60 }
61
onBlowfishToggled(bool blowfish)62 void KNewWalletDialogIntro::onBlowfishToggled(bool blowfish)
63 {
64 setFinalPage(blowfish);
65 }
66
isBlowfish() const67 bool KNewWalletDialogIntro::isBlowfish() const
68 {
69 return _ui.radioBlowfish->isChecked();
70 }
71
nextId() const72 int KNewWalletDialogIntro::nextId() const
73 {
74 if (isBlowfish()) {
75 return -1;
76 } else {
77 return qobject_cast<const KNewWalletDialog *>(wizard())->gpgId();
78 }
79 }
80
KNewWalletDialogGpg(const QString & appName,const QString & walletName,QWidget * parent)81 KNewWalletDialogGpg::KNewWalletDialogGpg(const QString &appName, const QString &walletName, QWidget *parent)
82 : QWizardPage(parent)
83 , _alreadyInitialized(false)
84 , _complete(false)
85 {
86 _ui.setupUi(this);
87 }
88
89 struct AddKeyToList {
90 QTableWidget *_list;
91 int _row;
AddKeyToListKWallet::AddKeyToList92 AddKeyToList(QTableWidget *list)
93 : _list(list)
94 , _row(0)
95 {
96 }
operator ()KWallet::AddKeyToList97 void operator()(const GpgME::Key &k)
98 {
99 GpgME::UserID uid = k.userID(0);
100 QString name(uid.name());
101 if (uid.comment()) {
102 name = QStringLiteral("%1 (%2)").arg(name, uid.comment());
103 }
104 _list->setItem(_row, 0, new QTableWidgetItem(name));
105 _list->setItem(_row, 1, new QTableWidgetItem(uid.email()));
106 _list->setItem(_row, 2, new QTableWidgetItem(k.shortKeyID()));
107 QVariant varKey;
108 varKey.setValue(k);
109 _list->item(_row, 0)->setData(Qt::UserRole, varKey);
110 ++_row;
111 }
112 };
113
initializePage()114 void KNewWalletDialogGpg::initializePage()
115 {
116 if (_alreadyInitialized) {
117 return;
118 }
119
120 registerField(QStringLiteral("key"), this);
121
122 GpgME::initializeLibrary();
123 GpgME::Error err = GpgME::checkEngine(GpgME::OpenPGP);
124 if (err) {
125 qCDebug(KWALLETD_LOG) << "OpenPGP not supported on your system!";
126 KMessageBox::error(this,
127 i18n("The GpgME library failed to initialize for the OpenPGP protocol. Please check your system's configuration then try again."));
128 Q_EMIT completeChanged();
129 return;
130 }
131 std::shared_ptr<GpgME::Context> _ctx(GpgME::Context::createForProtocol(GpgME::OpenPGP));
132 if (!_ctx) {
133 KMessageBox::error(this,
134 i18n("The GpgME library failed to initialize for the OpenPGP protocol. Please check your system's configuration then try again."));
135 Q_EMIT completeChanged();
136 return;
137 }
138 _ctx->setKeyListMode(GpgME::Local);
139
140 std::vector<GpgME::Key> keys;
141 err = _ctx->startKeyListing();
142 while (!err) {
143 GpgME::Key k = _ctx->nextKey(err);
144 if (err) {
145 break;
146 }
147 if (!k.isInvalid() && k.canEncrypt() && (k.ownerTrust() == GpgME::Key::Ultimate)) {
148 keys.push_back(k);
149 }
150 }
151 _ctx->endKeyListing();
152
153 if (keys.size() == 0) {
154 KMessageBox::error(this,
155 i18n("Seems that your system has no keys suitable for encryption. Please set-up at least one encryption key, then try again."));
156 Q_EMIT completeChanged();
157 return;
158 }
159
160 _ui.listCertificates->setRowCount(keys.size());
161 std::for_each(keys.begin(), keys.end(), AddKeyToList(_ui.listCertificates));
162 _ui.listCertificates->resizeColumnsToContents();
163 _ui.listCertificates->setCurrentCell(0, 0);
164
165 _alreadyInitialized = true;
166 }
167
onItemSelectionChanged()168 void KNewWalletDialogGpg::onItemSelectionChanged()
169 {
170 _complete = _ui.listCertificates->currentRow() >= 0;
171 QVariant varKey = _ui.listCertificates->item(_ui.listCertificates->currentRow(), 0)->data(Qt::UserRole);
172 setField(QStringLiteral("key"), varKey);
173 Q_EMIT completeChanged();
174 }
175
isComplete() const176 bool KNewWalletDialogGpg::isComplete() const
177 {
178 return _complete;
179 }
180
validateCurrentPage()181 bool KNewWalletDialogGpg::validateCurrentPage()
182 {
183 return false;
184 }
185
186 } // namespace
187 #include "moc_knewwalletdialog.cpp"
188