1 /*  dialogs/gencardkeydialog.cpp
2 
3     This file is part of Kleopatra, the KDE keymanager
4     SPDX-FileCopyrightText: 2017 Bundesamt für Sicherheit in der Informationstechnik
5     SPDX-FileContributor: Intevation GmbH
6 
7     SPDX-License-Identifier: GPL-2.0-or-later
8 */
9 
10 #include "gencardkeydialog.h"
11 
12 #include "utils/userinfo.h"
13 
14 #include <QDialogButtonBox>
15 #include <QLineEdit>
16 #include <QComboBox>
17 #include <QCheckBox>
18 #include <QGridLayout>
19 #include <QVBoxLayout>
20 #include <QPushButton>
21 #include <QLabel>
22 
23 #include <KEmailAddress>
24 #include <KLocalizedString>
25 #include <KColorScheme>
26 
27 #include "kleopatra_debug.h"
28 
29 using namespace Kleo;
30 
31 class GenCardKeyDialog::Private
32 {
33 public:
Private(GenCardKeyDialog * qq,KeyAttributes requiredAttributes)34     Private(GenCardKeyDialog *qq, KeyAttributes requiredAttributes): q(qq),
35         mOkButton(nullptr),
36         mNameEdit(nullptr),
37         mEmailEdit(nullptr),
38         mInvalidEmailLabel(nullptr),
39         mAlgorithmCombo(nullptr),
40         mBackupCheckBox(nullptr)
41     {
42         auto vBox = new QVBoxLayout(q);
43         auto grid = new QGridLayout;
44 
45         int row = 0;
46 
47         if (requiredAttributes & KeyOwnerName) {
48             auto nameLabel = new QLabel(i18n("Name:"));
49             mNameEdit = new QLineEdit(userFullName());
50 
51             grid->addWidget(nameLabel, row, 0);
52             grid->addWidget(mNameEdit, row++, 1);
53         }
54         if (requiredAttributes & KeyOwnerEmail) {
55             auto mailLabel = new QLabel(i18n("EMail:"));
56             mEmailEdit = new QLineEdit(userEmailAddress());
57             connect(mEmailEdit, &QLineEdit::textChanged, q, [this]() {checkAcceptable();});
58             mInvalidEmailLabel = new QLabel(QStringLiteral("<font size='small' color='%1'>%2</font>").arg(
59                 KColorScheme(QPalette::Active, KColorScheme::View).foreground(KColorScheme::NegativeText).color().name(), i18n("Invalid EMail")));
60 
61             grid->addWidget(mailLabel, row, 0);
62             grid->addWidget(mEmailEdit, row++, 1);
63             grid->addWidget(mInvalidEmailLabel, row++, 1);
64         }
65         if (requiredAttributes & KeyAlgorithm) {
66             auto algorithmLabel = new QLabel(i18n("Algorithm:"));
67             mAlgorithmCombo = new QComboBox;
68 
69             grid->addWidget(algorithmLabel, row, 0);
70             grid->addWidget(mAlgorithmCombo, row++, 1);
71         }
72         if (requiredAttributes & LocalKeyBackup) {
73             mBackupCheckBox = new QCheckBox(i18n("Backup encryption key"));
74             mBackupCheckBox->setToolTip(i18n("Backup the encryption key in a file.") + QStringLiteral("<br/>") +
75                                         i18n("You will be asked for a passphrase to protect that file during key generation."));
76             mBackupCheckBox->setChecked(true);
77 
78             grid->addWidget(mBackupCheckBox, row++, 0, 1, 2);
79         }
80 
81         vBox->addLayout(grid);
82 
83         auto bbox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, qq);
84 
85         mOkButton = bbox->button(QDialogButtonBox::Ok);
86 
87         mOkButton->setDefault(true);
88         mOkButton->setShortcut(Qt::CTRL | Qt::Key_Return);
89         connect(bbox, &QDialogButtonBox::rejected, q, [this]() {q->reject();});
90         connect(bbox, &QDialogButtonBox::accepted, q, [this]() {accept();});
91 
92         vBox->addWidget(bbox);
93 
94         q->setMinimumWidth(400);
95 
96         checkAcceptable();
97     }
98 
accept()99     void accept()
100     {
101         if (mNameEdit) {
102             params.name = mNameEdit->text();
103         }
104         if (mEmailEdit) {
105             params.email = mEmailEdit->text();
106         }
107         if (mAlgorithmCombo) {
108             params.algorithm = mAlgorithmCombo->currentData().toByteArray().toStdString();
109         }
110         if (mBackupCheckBox) {
111             params.backup = mBackupCheckBox->isChecked();
112         }
113         q->accept();
114     }
115 
setSupportedAlgorithms(const std::vector<std::pair<std::string,QString>> & algorithms,const std::string & defaultAlgo)116     void setSupportedAlgorithms(const std::vector<std::pair<std::string, QString>> &algorithms, const std::string &defaultAlgo)
117     {
118         if (!mAlgorithmCombo) {
119             qCWarning(KLEOPATRA_LOG) << "GenCardKeyDialog::setSupportedAlgorithms() called, but algorithm no required key attribute";
120             return;
121         }
122 
123         mAlgorithmCombo->clear();
124         for (auto algorithm: algorithms) {
125             mAlgorithmCombo->addItem(algorithm.second, QByteArray::fromStdString(algorithm.first));
126         }
127         mAlgorithmCombo->setCurrentIndex(mAlgorithmCombo->findData(QByteArray::fromStdString(defaultAlgo)));
128     }
129 
checkAcceptable()130     void checkAcceptable()
131     {
132         // We only require a valid mail address
133         if (!mEmailEdit) {
134             return;
135         }
136         const QString mail = mEmailEdit->text();
137         if (!mail.isEmpty() &&
138             KEmailAddress::isValidSimpleAddress(mail)) {
139             mOkButton->setEnabled(true);
140             mInvalidEmailLabel->hide();
141             return;
142         }
143         if (!mail.isEmpty()) {
144             mInvalidEmailLabel->show();
145         } else {
146             mInvalidEmailLabel->hide();
147         }
148         mOkButton->setEnabled(false);
149     }
150 
151     GenCardKeyDialog *const q;
152     KeyParams params;
153     QPushButton *mOkButton;
154     QLineEdit *mNameEdit;
155     QLineEdit *mEmailEdit;
156     QLabel *mInvalidEmailLabel;
157     QComboBox *mAlgorithmCombo;
158     QCheckBox *mBackupCheckBox;
159 };
160 
GenCardKeyDialog(KeyAttributes requiredAttributes,QWidget * parent)161 GenCardKeyDialog::GenCardKeyDialog(KeyAttributes requiredAttributes, QWidget *parent) : QDialog(parent),
162     d(new Private(this, requiredAttributes))
163 {
164 }
165 
setSupportedAlgorithms(const std::vector<std::pair<std::string,QString>> & algorithms,const std::string & defaultAlgo)166 void GenCardKeyDialog::setSupportedAlgorithms(const std::vector<std::pair<std::string, QString>> &algorithms, const std::string &defaultAlgo)
167 {
168     d->setSupportedAlgorithms(algorithms, defaultAlgo);
169 }
170 
getKeyParams() const171 GenCardKeyDialog::KeyParams GenCardKeyDialog::getKeyParams() const
172 {
173     return d->params;
174 }
175