Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F34621322
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
12 KB
Subscribers
None
View Options
diff --git a/src/dialogs/certificatedetailsinputwidget.cpp b/src/dialogs/certificatedetailsinputwidget.cpp
index d9de01194..ccdf45a90 100644
--- a/src/dialogs/certificatedetailsinputwidget.cpp
+++ b/src/dialogs/certificatedetailsinputwidget.cpp
@@ -1,353 +1,353 @@
/* -*- mode: c++; c-basic-offset:4 -*-
dialogs/certificatedetailsinputwidget.cpp
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2008 Klarälvdalens Datakonsult AB
SPDX-FileCopyrightText: 2020 g10 Code GmbH
SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "certificatedetailsinputwidget.h"
#include <utils/validation.h>
#include <Libkleo/Dn>
#include <Libkleo/OidMap>
#include <Libkleo/Stl_Util>
#include <KConfigGroup>
#include <KEMailSettings>
#include <KLocalizedString>
#include <KSharedConfig>
#include <QLabel>
#include <QLineEdit>
#include <QValidator>
#include <QVBoxLayout>
#include "kleopatra_debug.h"
using namespace Kleo;
using namespace Kleo::Dialogs;
namespace
{
struct Line {
QString attr;
QString label;
QString regex;
QLineEdit *edit;
bool required;
};
QString attributeFromKey(QString key)
{
return key.remove(QLatin1Char('!'));
}
QString attributeLabel(const QString &attr)
{
if (attr.isEmpty()) {
return QString();
}
const QString label = DNAttributeMapper::instance()->name2label(attr);
if (!label.isEmpty()) {
return i18nc("Format string for the labels in the \"Your Personal Data\" page",
"%1 (%2)", label, attr);
} else {
return attr;
}
}
QLineEdit * addRow(QGridLayout *l, const QString &label, const QString &preset, QValidator *validator, bool readonly, bool required)
{
Q_ASSERT(l);
QLabel *lb = new QLabel(l->parentWidget());
lb->setText(i18nc("interpunctation for labels", "%1:", label));
QLineEdit *le = new QLineEdit(l->parentWidget());
le->setText(preset);
delete le->validator();
if (validator) {
if (!validator->parent()) {
validator->setParent(le);
}
le->setValidator(validator);
}
le->setReadOnly(readonly && le->hasAcceptableInput());
QLabel *reqLB = new QLabel(l->parentWidget());
reqLB->setText(required ? i18n("(required)") : i18n("(optional)"));
const int row = l->rowCount();
l->addWidget(lb, row, 0);
l->addWidget(le, row, 1);
l->addWidget(reqLB, row, 2);
return le;
}
bool hasIntermediateInput(const QLineEdit *le)
{
QString text = le->text();
int pos = le->cursorPosition();
const QValidator *const v = le->validator();
return v && v->validate(text, pos) == QValidator::Intermediate;
}
QString requirementsAreMet(const QVector<Line> &lines)
{
for (const Line &line : lines) {
const QLineEdit *le = line.edit;
if (!le) {
continue;
}
qCDebug(KLEOPATRA_LOG) << "requirementsAreMet(): checking \"" << line.attr << "\" against \"" << le->text() << "\":";
if (le->text().trimmed().isEmpty()) {
if (line.required) {
if (line.regex.isEmpty()) {
return xi18nc("@info", "<interface>%1</interface> is required, but empty.", line.label);
} else {
return xi18nc("@info", "<interface>%1</interface> is required, but empty.<nl/>"
"Local Admin rule: <icode>%2</icode>", line.label, line.regex);
}
}
} else if (hasIntermediateInput(le)) {
if (line.regex.isEmpty()) {
return xi18nc("@info", "<interface>%1</interface> is incomplete.", line.label);
} else {
return xi18nc("@info", "<interface>%1</interface> is incomplete.<nl/>"
"Local Admin rule: <icode>%2</icode>", line.label, line.regex);
}
} else if (!le->hasAcceptableInput()) {
if (line.regex.isEmpty()) {
return xi18nc("@info", "<interface>%1</interface> is invalid.", line.label);
} else {
return xi18nc("@info", "<interface>%1</interface> is invalid.<nl/>"
"Local Admin rule: <icode>%2</icode>", line.label, line.regex);
}
}
}
return QString();
}
}
class CertificateDetailsInputWidget::Private
{
friend class ::Kleo::Dialogs::CertificateDetailsInputWidget;
CertificateDetailsInputWidget *const q;
struct {
QGridLayout *gridLayout;
QVector<Line> lines;
QLineEdit *dn;
QLabel *error;
} ui;
public:
Private(CertificateDetailsInputWidget *qq)
: q(qq)
{
auto mainLayout = new QVBoxLayout(q);
ui.gridLayout = new QGridLayout();
mainLayout->addLayout(ui.gridLayout);
createForm();
mainLayout->addStretch(1);
ui.dn = new QLineEdit();
ui.dn->setFrame(false);
ui.dn->setAlignment(Qt::AlignCenter);
ui.dn->setReadOnly(true);
mainLayout->addWidget(ui.dn);
ui.error = new QLabel();
{
QSizePolicy sizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
sizePolicy.setHeightForWidth(ui.error->sizePolicy().hasHeightForWidth());
ui.error->setSizePolicy(sizePolicy);
}
{
QPalette palette;
QBrush brush(QColor(255, 0, 0, 255));
brush.setStyle(Qt::SolidPattern);
palette.setBrush(QPalette::Active, QPalette::WindowText, brush);
palette.setBrush(QPalette::Inactive, QPalette::WindowText, brush);
QBrush brush1(QColor(114, 114, 114, 255));
brush1.setStyle(Qt::SolidPattern);
palette.setBrush(QPalette::Disabled, QPalette::WindowText, brush1);
ui.error->setPalette(palette);
}
ui.error->setTextFormat(Qt::RichText);
// set error label to have a fixed height of two lines:
ui.error->setText(QStringLiteral("2<br>1"));
ui.error->setFixedHeight(ui.error->minimumSizeHint().height());
ui.error->clear();
mainLayout->addWidget(ui.error);
// select the preset text in the first line edit
if (!ui.lines.empty()) {
ui.lines.first().edit->selectAll();
}
// explicitly update DN and check requirements after setup is complete
updateDN();
checkRequirements();
}
~Private()
{
// remember current attribute values as presets for next certificate
KConfigGroup config(KSharedConfig::openConfig(), "CertificateCreationWizard");
for ( const Line &line : ui.lines ) {
const QString attr = attributeFromKey(line.attr);
const QString value = line.edit->text().trimmed();
config.writeEntry(attr, value);
}
config.sync();
}
void createForm()
{
const KEMailSettings emailSettings;
const KConfigGroup config(KSharedConfig::openConfig(), "CertificateCreationWizard");
QStringList attrOrder = config.readEntry("DNAttributeOrder", QStringList());
if (attrOrder.empty()) {
attrOrder << QStringLiteral("CN!")
<< QStringLiteral("EMAIL!")
<< QStringLiteral("L")
<< QStringLiteral("OU")
- << QStringLiteral("O!")
- << QStringLiteral("C!");
+ << QStringLiteral("O")
+ << QStringLiteral("C");
}
for (const QString &rawKey : attrOrder) {
const QString key = rawKey.trimmed().toUpper();
const QString attr = attributeFromKey(key);
if (attr.isEmpty()) {
continue;
}
const QString defaultPreset = (attr == QLatin1String("CN")) ? emailSettings.getSetting(KEMailSettings::RealName) :
(attr == QLatin1String("EMAIL")) ? emailSettings.getSetting(KEMailSettings::EmailAddress) :
QString();
const QString preset = config.readEntry(attr, defaultPreset);
const bool required = key.endsWith(QLatin1Char('!'));
const bool readonly = config.isEntryImmutable(attr);
const QString label = config.readEntry(attr + QLatin1String("_label"),
attributeLabel(attr));
const QString regex = config.readEntry(attr + QLatin1String("_regex"));
QValidator *validator = nullptr;
if (attr == QLatin1String("EMAIL")) {
validator = regex.isEmpty() ? Validation::email() : Validation::email(QRegExp(regex));
} else if (!regex.isEmpty()) {
validator = new QRegExpValidator(QRegExp(regex), nullptr);
}
QLineEdit *le = addRow(ui.gridLayout, label, preset, validator, readonly, required);
const Line line = { attr, label, regex, le, required };
ui.lines.push_back(line);
if (attr != QLatin1String("EMAIL")) {
connect(le, &QLineEdit::textChanged, [this] () { updateDN(); });
}
connect(le, &QLineEdit::textChanged, [this] () { checkRequirements(); });
}
}
void updateDN()
{
ui.dn->setText(cmsDN());
}
QString cmsDN() const
{
DN dn;
for ( const Line &line : ui.lines ) {
const QString text = line.edit->text().trimmed();
if (text.isEmpty()) {
continue;
}
QString attr = attributeFromKey(line.attr);
if (attr == QLatin1String("EMAIL")) {
continue;
}
if (const char *const oid = oidForAttributeName(attr)) {
attr = QString::fromUtf8(oid);
}
dn.append(DN::Attribute(attr, text));
}
return dn.dn();
}
void checkRequirements()
{
const QString error = requirementsAreMet(ui.lines);
ui.error->setText(error);
Q_EMIT q->validityChanged(error.isEmpty());
}
QLineEdit * attributeWidget(const QString &attribute)
{
for ( const Line &line : ui.lines ) {
if (attributeFromKey(line.attr) == attribute) {
return line.edit;
}
}
qCWarning(KLEOPATRA_LOG) << "CertificateDetailsInputWidget: No widget for attribute" << attribute;
return nullptr;
}
void setAttributeValue(const QString &attribute, const QString &value)
{
QLineEdit *w = attributeWidget(attribute);
if (w) {
w->setText(value);
}
}
QString attributeValue(const QString &attribute)
{
const QLineEdit *w = attributeWidget(attribute);
return w ? w->text().trimmed() : QString();
}
};
CertificateDetailsInputWidget::CertificateDetailsInputWidget(QWidget *parent)
: QWidget(parent)
, d(new Private(this))
{
}
CertificateDetailsInputWidget::~CertificateDetailsInputWidget()
{
}
void CertificateDetailsInputWidget::setName(const QString &name)
{
d->setAttributeValue(QStringLiteral("CN"), name);
}
void CertificateDetailsInputWidget::setEmail(const QString &email)
{
d->setAttributeValue(QStringLiteral("EMAIL"), email);
}
QString CertificateDetailsInputWidget::email() const
{
return d->attributeValue(QStringLiteral("EMAIL"));
}
QString CertificateDetailsInputWidget::dn() const
{
return d->ui.dn->text();
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Tue, Jan 20, 1:12 AM (6 h, 12 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
e3/eb/3ccda53814a97bb975598b9fb05b
Attached To
rKLEOPATRA Kleopatra
Event Timeline
Log In to Comment