File indexing completed on 2024-06-23 05:13:37

0001 /* -*- mode: c++; c-basic-offset:4 -*-
0002     commands/changepassphrasecommand.cpp
0003 
0004     This file is part of Kleopatra, the KDE keymanager
0005     SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 #include <config-kleopatra.h>
0011 
0012 #include "changepassphrasecommand.h"
0013 
0014 #include "command_p.h"
0015 
0016 #include <Libkleo/Formatting>
0017 
0018 #include <QGpgME/ChangePasswdJob>
0019 #include <QGpgME/Protocol>
0020 
0021 #include <gpgme++/key.h>
0022 
0023 #include "kleopatra_debug.h"
0024 #include <KLocalizedString>
0025 
0026 #include <gpg-error.h>
0027 
0028 using namespace Kleo;
0029 using namespace Kleo::Commands;
0030 using namespace GpgME;
0031 using namespace QGpgME;
0032 
0033 class ChangePassphraseCommand::Private : public Command::Private
0034 {
0035     friend class ::Kleo::Commands::ChangePassphraseCommand;
0036     ChangePassphraseCommand *q_func() const
0037     {
0038         return static_cast<ChangePassphraseCommand *>(q);
0039     }
0040 
0041 public:
0042     explicit Private(ChangePassphraseCommand *qq, KeyListController *c);
0043     ~Private() override;
0044 
0045     void init();
0046 
0047 private:
0048     void slotResult(const Error &err);
0049 
0050 private:
0051     void createJob();
0052     void startJob();
0053     void showErrorDialog(const Error &error);
0054     void showSuccessDialog();
0055 
0056 private:
0057     GpgME::Key key;
0058     QPointer<ChangePasswdJob> job;
0059 };
0060 
0061 ChangePassphraseCommand::Private *ChangePassphraseCommand::d_func()
0062 {
0063     return static_cast<Private *>(d.get());
0064 }
0065 const ChangePassphraseCommand::Private *ChangePassphraseCommand::d_func() const
0066 {
0067     return static_cast<const Private *>(d.get());
0068 }
0069 
0070 #define d d_func()
0071 #define q q_func()
0072 
0073 ChangePassphraseCommand::Private::Private(ChangePassphraseCommand *qq, KeyListController *c)
0074     : Command::Private(qq, c)
0075     , key()
0076     , job()
0077 {
0078 }
0079 
0080 ChangePassphraseCommand::Private::~Private()
0081 {
0082     qCDebug(KLEOPATRA_LOG);
0083 }
0084 
0085 ChangePassphraseCommand::ChangePassphraseCommand(KeyListController *c)
0086     : Command(new Private(this, c))
0087 {
0088     d->init();
0089 }
0090 
0091 ChangePassphraseCommand::ChangePassphraseCommand(QAbstractItemView *v, KeyListController *c)
0092     : Command(v, new Private(this, c))
0093 {
0094     d->init();
0095 }
0096 
0097 ChangePassphraseCommand::ChangePassphraseCommand(const GpgME::Key &key)
0098     : Command(key, new Private(this, nullptr))
0099 {
0100     d->init();
0101 }
0102 
0103 void ChangePassphraseCommand::Private::init()
0104 {
0105 }
0106 
0107 ChangePassphraseCommand::~ChangePassphraseCommand()
0108 {
0109     qCDebug(KLEOPATRA_LOG);
0110 }
0111 
0112 void ChangePassphraseCommand::doStart()
0113 {
0114     const std::vector<Key> keys = d->keys();
0115     if (keys.size() != 1 || !keys.front().hasSecret()) {
0116         d->finished();
0117         return;
0118     }
0119 
0120     d->key = keys.front();
0121 
0122     d->createJob();
0123     d->startJob();
0124 }
0125 
0126 void ChangePassphraseCommand::Private::startJob()
0127 {
0128     const Error err = job ? job->start(key) : Error::fromCode(GPG_ERR_NOT_SUPPORTED);
0129     if (err) {
0130         showErrorDialog(err);
0131         finished();
0132     }
0133 }
0134 
0135 void ChangePassphraseCommand::Private::slotResult(const Error &err)
0136 {
0137     if (err.isCanceled())
0138         ;
0139     else if (err) {
0140         showErrorDialog(err);
0141     } else {
0142         showSuccessDialog();
0143     }
0144     finished();
0145 }
0146 
0147 void ChangePassphraseCommand::doCancel()
0148 {
0149     qCDebug(KLEOPATRA_LOG);
0150     if (d->job) {
0151         d->job->slotCancel();
0152     }
0153 }
0154 
0155 void ChangePassphraseCommand::Private::createJob()
0156 {
0157     Q_ASSERT(!job);
0158 
0159     const auto backend = (key.protocol() == GpgME::OpenPGP) ? QGpgME::openpgp() : QGpgME::smime();
0160     if (!backend) {
0161         return;
0162     }
0163 
0164     ChangePasswdJob *const j = backend->changePasswdJob();
0165     if (!j) {
0166         return;
0167     }
0168 
0169     connect(j, &QGpgME::Job::jobProgress, q, &Command::progress);
0170     connect(j, &ChangePasswdJob::result, q, [this](const GpgME::Error &result) {
0171         slotResult(result);
0172     });
0173 
0174     job = j;
0175 }
0176 
0177 void ChangePassphraseCommand::Private::showErrorDialog(const Error &err)
0178 {
0179     error(i18n("<p>An error occurred while trying to change "
0180                "the passphrase for <b>%1</b>:</p><p>%2</p>",
0181                Formatting::formatForComboBox(key),
0182                Formatting::errorAsString(err)),
0183           i18n("Passphrase Change Error"));
0184 }
0185 
0186 void ChangePassphraseCommand::Private::showSuccessDialog()
0187 {
0188     information(i18n("Passphrase changed successfully."), i18n("Passphrase Change Succeeded"));
0189 }
0190 
0191 #undef d
0192 #undef q
0193 
0194 #include "moc_changepassphrasecommand.cpp"