Commit 9dfd273c authored by Ingo Klöcker's avatar Ingo Klöcker
Browse files

After creating the CSR write it to disk asking the user for a location

GnuPG-bug-id: 5127
parent 40b9a421
......@@ -148,7 +148,6 @@ set(_kleopatra_SRCS
dialogs/pivcardapplicationadministrationkeyinputdialog.cpp
dialogs/certificatedetailsinputwidget.cpp
dialogs/createcsrforcardkeydialog.cpp
dialogs/csrcreationresultdialog.cpp
crypto/controller.cpp
crypto/certificateresolver.cpp
......
......@@ -15,17 +15,20 @@
#include "cardcommand_p.h"
#include "dialogs/createcsrforcardkeydialog.h"
#include "dialogs/csrcreationresultdialog.h"
#include "smartcard/pivcard.h"
#include "smartcard/readerstatus.h"
#include "utils/filedialog.h"
#include "utils/keyparameters.h"
#include <Libkleo/Formatting>
#include <KLocalizedString>
#include <QDateTime>
#include <QFile>
#include <KLocalizedString>
#include <QUrl>
#include <QGpgME/Protocol>
......@@ -65,6 +68,8 @@ private:
void slotDialogRejected();
void slotResult(const KeyGenerationResult &result, const QByteArray &request);
QUrl saveRequest(const QByteArray &request);
void ensureDialogCreated();
private:
......@@ -194,16 +199,61 @@ void CreateCSRForCardKeyCommand::Private::slotResult(const KeyGenerationResult &
error(i18nc("@info", "Creating a CSR for the card key failed:\n%1", QString::fromUtf8(result.error().asString())),
i18nc("@title", "Error"));
} else {
auto resultDialog = new CSRCreationResultDialog;
applyWindowID(resultDialog);
resultDialog->setAttribute(Qt::WA_DeleteOnClose);
resultDialog->setCSR(request);
resultDialog->show();
const QUrl url = saveRequest(request);
if (!url.isEmpty()) {
information(xi18nc("@info", "<para>Successfully wrote request to <filename>%1</filename>.</para>"
"<para>You should now send the request to the Certification Authority (CA).</para>",
url.toLocalFile()),
i18nc("@title", "Request Saved"));
}
}
finished();
}
namespace
{
struct SaveToFileResult {
QUrl url;
QString errorMessage;
};
SaveToFileResult saveRequestToFile(const QString &filename, const QByteArray &request, QIODevice::OpenMode mode)
{
QFile file(filename);
if (file.open(mode)) {
const auto bytesWritten = file.write(request);
if (bytesWritten < request.size()) {
return { QUrl(), file.errorString() };
}
return { QUrl::fromLocalFile(file.fileName()), QString() };
}
return { QUrl(), file.errorString() };
}
}
QUrl CreateCSRForCardKeyCommand::Private::saveRequest(const QByteArray &request)
{
const QString proposedFilename = QLatin1String("request_%1.p10").arg(QDateTime::currentDateTime().toString(QStringLiteral("yyyy-MM-dd_HHmmss")));
while (true) {
const QString filePath = FileDialog::getSaveFileNameEx(
parentWidgetOrView(), i18nc("@title", "Save Request"), QStringLiteral("save_csr"), proposedFilename, i18n("PKCS#10 Requests (*.p10)"));
if (filePath.isEmpty()) {
// user canceled the dialog
return QUrl();
}
const auto result = saveRequestToFile(filePath, request, QIODevice::NewOnly);
if (result.url.isEmpty()) {
qCDebug(KLEOPATRA_LOG) << "Writing request to file" << filePath << "failed:" << result.errorMessage;
error(xi18nc("@info", "<para>Saving the request failed.</para><para><message>%1</message></para>", result.errorMessage),
i18nc("@title", "Error Saving Request"));
} else {
return result.url;
}
}
}
void CreateCSRForCardKeyCommand::Private::ensureDialogCreated()
{
if (dialog) {
......
/* -*- mode: c++; c-basic-offset:4 -*-
dialogs/csrcreationresultdialog.h
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2020 g10 Code GmbH
SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "csrcreationresultdialog.h"
#include <KConfigGroup>
#include <KGuiItem>
#include <KLocalizedString>
#include <KSeparator>
#include <KSharedConfig>
#include <KStandardGuiItem>
#include <QDialogButtonBox>
#include <QLabel>
#include <QPlainTextEdit>
#include <QPushButton>
#include <QVBoxLayout>
using namespace Kleo;
using namespace Kleo::Dialogs;
class CSRCreationResultDialog::Private
{
friend class ::Kleo::Dialogs::CSRCreationResultDialog;
CSRCreationResultDialog *const q;
struct {
QPlainTextEdit *csrBrowser = nullptr;
QDialogButtonBox *buttonBox = nullptr;
} ui;
QByteArray csr;
public:
Private(CSRCreationResultDialog *qq)
: q(qq)
{
auto mainLayout = new QVBoxLayout(q);
{
auto label = new QLabel(i18n("The certificate signing request was created successfully. Please find the result and suggested next steps below."));
label->setWordWrap(true);
mainLayout->addWidget(label);
}
mainLayout->addWidget(new KSeparator(Qt::Horizontal));
ui.csrBrowser = new QPlainTextEdit();
ui.csrBrowser->setLineWrapMode(QPlainTextEdit::NoWrap);
ui.csrBrowser->setReadOnly(true);
ui.csrBrowser->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard);
mainLayout->addWidget(ui.csrBrowser);
mainLayout->addWidget(new KSeparator(Qt::Horizontal));
ui.buttonBox = new QDialogButtonBox(QDialogButtonBox::Close);
KGuiItem::assign(ui.buttonBox->button(QDialogButtonBox::Close), KStandardGuiItem::close());
connect(ui.buttonBox, &QDialogButtonBox::clicked, q, &QDialog::close);
mainLayout->addWidget(ui.buttonBox);
// calculate default size with enough space for the text edit
const auto fm = ui.csrBrowser->fontMetrics();
const QSize sizeHint = q->sizeHint();
const QSize defaultSize = QSize(qMax(sizeHint.width(), 90 * fm.horizontalAdvance(QLatin1Char('x'))),
sizeHint.height() - ui.csrBrowser->sizeHint().height() + 10 * fm.lineSpacing());
restoreGeometry(defaultSize);
}
~Private()
{
saveGeometry();
}
private:
void saveGeometry()
{
KConfigGroup cfgGroup(KSharedConfig::openConfig(), "CSRCreationResultDialog");
cfgGroup.writeEntry("Size", q->size());
cfgGroup.sync();
}
void restoreGeometry(const QSize &defaultSize)
{
KConfigGroup cfgGroup(KSharedConfig::openConfig(), "CSRCreationResultDialog");
const QSize size = cfgGroup.readEntry("Size", defaultSize);
if (size.isValid()) {
q->resize(size);
}
}
};
CSRCreationResultDialog::CSRCreationResultDialog(QWidget *parent)
: QDialog(parent)
, d(new Private(this))
{
setWindowTitle(i18nc("@title:window", "CSR Created"));
}
CSRCreationResultDialog::~CSRCreationResultDialog()
{
}
void CSRCreationResultDialog::setCSR(const QByteArray &csr)
{
d->csr = csr;
d->ui.csrBrowser->setPlainText(QString::fromLatin1(csr));
}
/* -*- mode: c++; c-basic-offset:4 -*-
dialogs/csrcreationresultdialog.h
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2020 g10 Code GmbH
SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef __KLEOPATRA_DIALOGS_CSRCREATIONRESULTDIALOG_H__
#define __KLEOPATRA_DIALOGS_CSRCREATIONRESULTDIALOG_H__
#include <QDialog>
namespace Kleo
{
namespace Dialogs
{
class CSRCreationResultDialog : public QDialog
{
Q_OBJECT
public:
explicit CSRCreationResultDialog(QWidget *parent = nullptr);
~CSRCreationResultDialog() override;
void setCSR(const QByteArray &csr);
private:
class Private;
const std::unique_ptr<Private> d;
};
}
}
#endif // __KLEOPATRA_DIALOGS_CSRCREATIONRESULTDIALOG_H__
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment