Add update notification for Gpg4win

As Kleopatra is the main "App" for Gpg4win it has to take
responsibility of GUI for updates. This is state of the art
and was a long missing feature.

Update checks are done by GnuPG / Dirmngr to avoid the pitfalls
of TLS and update verification. This readds the gpg4win-compact
pic but only installs it under Windows.

This also bumps the version to 1.8.0 but Messagelib already
depends on that version and a previous commit expected the
gpgmepp_version header to work like it does in 1.8.0
parent 94a4a3f3
......@@ -10,6 +10,7 @@ set(KF5_VERSION "5.31.0")
set(KMIME_VERSION "5.4.40")
set(LIBKLEO_VERSION "5.4.40")
set(QT_REQUIRED_VERSION "5.6.0")
set(GPGME_REQUIRED_VERSION "1.8.0")
find_package(ECM ${KF5_VERSION} REQUIRED NO_MODULE)
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH})
......@@ -67,7 +68,8 @@ endif()
set(HAVE_QDBUS ${Qt5DBus_FOUND})
find_package(Gpgmepp "1.7.1" CONFIG REQUIRED)
find_package(Gpgmepp ${GPGME_REQUIRED_VERSION} CONFIG REQUIRED)
find_package(QGpgme ${GPGME_REQUIRED_VERSION} CONFIG REQUIRED)
# Kdepimlibs packages
find_package(KF5Libkleo ${LIBKLEO_VERSION} CONFIG REQUIRED)
......
if (WIN32)
set(EXTRAWINFILES gpg4win-compact.png)
endif()
install(FILES
kleopatra_wizard.png
kleopatra_wizard.svgz
kleopatra_splashscreen.png
kleopatra_splashscreen.svgz
gpg4win-compact.png
DESTINATION ${KDE_INSTALL_DATADIR}/kleopatra/pics
)
......@@ -117,6 +117,7 @@ set(_kleopatra_SRCS
dialogs/trustchainwidget.cpp
dialogs/subkeyswidget.cpp
dialogs/gencardkeydialog.cpp
dialogs/updatenotification.cpp
crypto/controller.cpp
crypto/certificateresolver.cpp
......
/* dialogs/updatenotification.cpp
This file is part of Kleopatra, the KDE keymanager
Copyright (c) 2017 Intevation GmbH
Kleopatra is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Kleopatra is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
In addition, as a special exception, the copyright holders give
permission to link the code of this program with any edition of
the Qt library by Trolltech AS, Norway (or with modified versions
of Qt that use the same license as Qt), and distribute linked
combinations including the two. You must obey the GNU General
Public License in all respects for all of the code used other than
Qt. If you modify this file, you may extend this exception to
your version of the file, but you are not obligated to do so. If
you do not wish to do so, delete this exception statement from
your version.
*/
#include "updatenotification.h"
#include "utils/gnupg-helper.h"
#include "kleopatra_debug.h"
#include <QIcon>
#include <QGridLayout>
#include <QCheckBox>
#include <QDialogButtonBox>
#include <QDesktopServices>
#include <QPushButton>
#include <QLabel>
#include <QUrl>
#include <QDateTime>
#include <KIconLoader>
#include <KLocalizedString>
#include <KConfigGroup>
#include <KSharedConfig>
#include <KMessageBox>
#include <QGpgME/CryptoConfig>
#include <QGpgME/Protocol>
#include <gpgme++/gpgmefw.h>
#include <gpgme++/swdbresult.h>
#include <gpgme++/error.h>
using namespace Kleo;
namespace
{
static void gpgconf_set_update_check(bool value)
{
auto conf = QGpgME::cryptoConfig();
auto entry = conf->entry(QStringLiteral("dirmngr"),
QStringLiteral("Enforcement"),
QStringLiteral("allow-version-check"));
if (!entry) {
qCDebug(KLEOPATRA_LOG) << "allow-version-check entry not found";
}
entry->setBoolValue(value);
conf->sync(true);
}
} // namespace
void UpdateNotification::checkUpdate(QWidget *parent, bool force)
{
#ifdef Q_OS_WIN
if (force) {
gpgconf_set_update_check(true);
}
const auto current = gpg4winVersion();
GpgME::Error err;
KConfigGroup updatecfg(KSharedConfig::openConfig(), "UpdateNotification");
const auto lastshown = updatecfg.readEntry("LastShown", QDateTime());
if (!force && lastshown.isValid() &&
lastshown.addSecs(20 * 60 * 60) > QDateTime::currentDateTime()) {
qDebug() << QDateTime::currentDateTime().addSecs(20 * 60 * 60);
return;
}
const auto results = GpgME::SwdbResult::query("gpg4win",
current.toUtf8().constData(),
&err);
if (err) {
qCDebug(KLEOPATRA_LOG) << "update check failed: " << err.asString();
return;
}
if (results.size() != 1) {
/* Should not happen */
qCDebug(KLEOPATRA_LOG) << "more then one result";
return;
}
const auto result = results[0];
if (result.update()) {
const QString newVersion = QStringLiteral("%1.%2.%3").arg(result.version().major)
.arg(result.version().minor)
.arg(result.version().patch);
qCDebug(KLEOPATRA_LOG) << "Have update to version:" << newVersion;
UpdateNotification notifier(parent, newVersion);
notifier.exec();
updatecfg.writeEntry("LastShown", QDateTime::currentDateTime());
updatecfg.sync();
} else {
qCDebug(KLEOPATRA_LOG) << "No update for:" << current;
if (force) {
KMessageBox::information(parent,
i18nc("@info",
"No update found in the available version database."),
i18nc("@title", "Up to date"));
}
}
#endif
}
UpdateNotification::UpdateNotification(QWidget *parent, const QString &version) :
QDialog(parent)
{
resize(400, 200);
auto lay = new QGridLayout;
setLayout (lay);
auto logo = new QLabel;
logo->setMaximumWidth(110);
setAttribute(Qt::WA_QuitOnClose, false);
KIconLoader *const il = KIconLoader::global();
const QString iconPath = il->iconPath(QLatin1String("gpg4win"),
KIconLoader::User);
logo->setPixmap(QIcon(iconPath).pixmap(100, 100));
auto label = new QLabel;
const QString boldVersion = QStringLiteral("<b>%1</b>").arg(version);
label->setText (i18nc("%1 is the version number", "Version %1 is available.", boldVersion) +
QStringLiteral("<br><br>") +
i18nc("Link to NEWS style changelog",
"See the <a href=\"https://www.gpg4win.org/change-history.html\">new features</a>."));
label->setOpenExternalLinks(true);
label->setTextInteractionFlags(Qt::TextBrowserInteraction);
label->setWordWrap(true);
setWindowTitle(i18n("Update available!"));
setWindowIcon(QIcon(QLatin1String("gpg4win")));
lay->addWidget(logo, 0, 0);
lay->addWidget(label, 0, 1);
const auto chk = new QCheckBox (i18n("Show this notification for future updates."));
lay->addWidget(chk, 1, 0, 1, -1);
chk->setChecked(true);
const auto bb = new QDialogButtonBox();
const auto b = bb->addButton(i18n("&Get update"), QDialogButtonBox::AcceptRole);
b->setDefault(true);
b->setIcon(QIcon::fromTheme("arrow-down"));
bb->addButton(QDialogButtonBox::Cancel);
lay->addWidget(bb, 2, 0, 1, -1);
connect (bb, &QDialogButtonBox::accepted, this, [this, chk]() {
QDesktopServices::openUrl(QUrl("https://www.gpg4win.org/download.html"));
KConfigGroup updatecfg(KSharedConfig::openConfig(), "UpdateNotification");
updatecfg.writeEntry("NeverShow", !chk->isChecked());
QDialog::accept();
});
connect (bb, &QDialogButtonBox::rejected, this, [this, chk]() {
KConfigGroup updatecfg(KSharedConfig::openConfig(), "UpdateNotification");
updatecfg.writeEntry("NeverShow", !chk->isChecked());
QDialog::reject();
});
}
/* dialogs/updatenotification.h
This file is part of Kleopatra, the KDE keymanager
Copyright (c) 2017 Intevation GmbH
Kleopatra is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Kleopatra is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
In addition, as a special exception, the copyright holders give
permission to link the code of this program with any edition of
the Qt library by Trolltech AS, Norway (or with modified versions
of Qt that use the same license as Qt), and distribute linked
combinations including the two. You must obey the GNU General
Public License in all respects for all of the code used other than
Qt. If you modify this file, you may extend this exception to
your version of the file, but you are not obligated to do so. If
you do not wish to do so, delete this exception statement from
your version.
*/
#ifndef DIALOGS_UPDATENOTIFICATION_H
#define DIALOGS_UPDATENOTIFICATION_H
#include <QString>
#include <QDialog>
namespace Kleo
{
/** Updatenotification for Gpg4win
*
* On Windows it is usual for Applications to notifiy the user
* about updates. To avoid network access in Kleopatra and
* to have only one TLS stack in our package this is implemented
* in dirmngr.
*/
class UpdateNotification : public QDialog
{
public:
static void checkUpdate(QWidget *parent, bool force = false);
UpdateNotification(QWidget *parent, const QString &version);};
} // namespace Kleo
#endif // DIALOGS_UPDATENOTIFICATION_H
<!DOCTYPE kpartgui >
<kpartgui name="kleopatra" version="500" >
<kpartgui name="kleopatra" version="501" >
<MenuBar>
<Menu name="file">
<text>&amp;File</text>
......@@ -80,6 +80,10 @@
<Action name="window_move_tab_left"/>
<Action name="window_move_tab_right"/>
</Menu>
<Menu name="help">
<text>&amp;Help</text>
<Action name="help_check_updates"/>
</Menu>
</MenuBar>
<ToolBar fullWidth="false" name="mainToolBar" iconText="TextUnderIcon">
......
......@@ -63,6 +63,8 @@
#include "commands/detailscommand.h"
#include "commands/newcertificatecommand.h"
#include "dialogs/updatenotification.h"
#include <KIconLoader>
#include <KLocalizedString>
#include "kleopatra_debug.h"
......@@ -488,6 +490,7 @@ void KleopatraApplication::openOrRaiseMainWindow()
d->connectConfigureDialog();
}
open_or_raise(mw);
UpdateNotification::checkUpdate(mw);
}
void KleopatraApplication::openOrRaiseConfigDialog()
......
......@@ -54,6 +54,8 @@
#include "utils/filedialog.h"
#include "utils/clipboardmenu.h"
#include "dialogs/updatenotification.h"
#include <KXMLGUIFactory>
#include <QApplication>
#include <KActionCollection>
......@@ -197,6 +199,11 @@ public:
i18n("Error Starting KWatchGnuPG"));
}
void forceUpdateCheck()
{
UpdateNotification::checkUpdate(q, true);
}
void slotConfigCommitted();
void slotContextMenuRequested(QAbstractItemView *, const QPoint &p)
{
......@@ -354,6 +361,12 @@ void MainWindow::Private::setupActions()
"tools_start_kwatchgnupg", i18n("GnuPG Log Viewer"), QString(),
"kwatchgnupg", q, SLOT(gnupgLogViewer()), QString(), false, true
},
#endif
#ifdef Q_OS_WIN
{
"help_check_updates", i18n("Check for updates"), QString(),
"gpg4win-compact", q, SLOT(forceUpdateCheck()), QString(), false, true
},
#endif
// most have been MOVED TO keylistcontroller.cpp
#if 0
......
......@@ -71,6 +71,7 @@ private:
Q_PRIVATE_SLOT(d, void slotContextMenuRequested(QAbstractItemView *, QPoint))
Q_PRIVATE_SLOT(d, void slotFocusQuickSearch())
Q_PRIVATE_SLOT(d, void toggleSmartcardView())
Q_PRIVATE_SLOT(d, void forceUpdateCheck())
};
#endif /* __KLEOPATRA_MAINWINDOW_DESKTOP_H__ */
......@@ -122,6 +122,23 @@ QStringList Kleo::gnupgFileWhitelist()
;
}
QString Kleo::gpg4winVersion()
{
QFile versionFile(gpg4winInstallPath() + QStringLiteral("/../VERSION"));
if (!versionFile.open(QIODevice::ReadOnly)) {
// No need to translate this should only be the case in development
// builds.
return QStringLiteral("Unknown (no VERSION file found)");
}
const QString g4wTag = QString::fromUtf8(versionFile.readLine());
if (!g4wTag.startsWith(QStringLiteral("gpg4win"))) {
// Hu? Something unknown
return QStringLiteral("Unknown (invalid VERSION file found)");
}
// Next line is version.
return QString::fromUtf8(versionFile.readLine()).trimmed();
}
QString Kleo::gpg4winInstallPath()
{
#ifdef Q_OS_WIN
......
......@@ -49,6 +49,7 @@ QString gpgPath();
QString gpgConfListDir(const char *which);
QString gpg4winInstallPath();
QString gpg4winVersion();
QString gnupgInstallPath();
const QString& paperKeyInstallPath();
......
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