From d9275434c7844671faab4a5619043ee48915d705 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Thu, 24 Nov 2022 07:16:43 +0200 Subject: [PATCH] Improve progress hiding (#1137) IB-7449 Signed-off-by: Raul Metsma Signed-off-by: Raul Metsma --- client/DigiDoc.cpp | 11 ++++++----- client/MainWindow.cpp | 5 ++--- client/QSigner.cpp | 8 +++----- client/QSmartCard.cpp | 6 ++---- client/Utils.h | 21 +++++++++++---------- client/dialogs/AccessCert.cpp | 13 +++++++------ client/dialogs/AccessCert.h | 6 +++--- client/dialogs/MobileProgress.cpp | 2 +- client/dialogs/SmartIDProgress.cpp | 7 ++++++- 9 files changed, 41 insertions(+), 38 deletions(-) diff --git a/client/DigiDoc.cpp b/client/DigiDoc.cpp index 04d51011e..b6970f53f 100644 --- a/client/DigiDoc.cpp +++ b/client/DigiDoc.cpp @@ -602,7 +602,7 @@ void DigiDoc::removeSignature( unsigned int num ) if(isError(num >= b->signatures().size(), tr("Missing signature"))) return; try { - modified = waitFor([this, num] { + modified = waitFor([&] { b->removeSignature(num); m_signatures.removeAt(num); return true; @@ -627,7 +627,7 @@ bool DigiDoc::saveAs(const QString &filename) { try { - return waitFor([&]{ + return waitFor([&] { parentContainer ? parentContainer->save(to(filename)) : b->save(to(filename)); return true; }); @@ -694,9 +694,10 @@ bool DigiDoc::sign(const QString &city, const QString &state, const QString &zip signer->setProfile("time-stamp"); qApp->waitForTSL( fileName() ); digidoc::Signature *s = b->sign(signer); - m_signatures.append(DigiDocSignature(s, this, false)); - modified = true; - return true; + return modified = waitFor([&] { + m_signatures.append(DigiDocSignature(s, this, false)); + return true; + }); } catch( const Exception &e ) { diff --git a/client/MainWindow.cpp b/client/MainWindow.cpp index a670062fc..7b712e262 100644 --- a/client/MainWindow.cpp +++ b/client/MainWindow.cpp @@ -915,8 +915,7 @@ void MainWindow::sign(F &&sign) return; } - AccessCert access(this); - if(!access.validate()) + if(!AccessCert(this).validate()) return; QString role, city, state, country, zip; @@ -940,7 +939,7 @@ void MainWindow::sign(F &&sign) else if(!sign(city, state, zip, country, role)) return; - access.increment(); + AccessCert::increment(); if(!save()) return; diff --git a/client/QSigner.cpp b/client/QSigner.cpp index a85417ac3..a6d6e8c00 100644 --- a/client/QSigner.cpp +++ b/client/QSigner.cpp @@ -213,8 +213,7 @@ QByteArray QSigner::decrypt(std::function &&func) return {}; } } while(status != QCryptoBackend::PinOK); - QByteArray result; - result = waitFor([&]{ return func(d->backend); }); + QByteArray result = waitFor(func, d->backend); QCardLock::instance().exclusiveUnlock(); d->backend->logout(); d->smartcard->reload(); // QSmartCard should also know that PIN1 is blocked. @@ -421,9 +420,8 @@ std::vector QSigner::sign(const std::string &method, const std::v throwException((tr("Failed to login token") + " " + QCryptoBackend::errorString(status)), Exception::PINFailed) } } while(status != QCryptoBackend::PinOK); - QByteArray sig = waitFor([&]{ - return d->backend->sign(methodToNID(method), QByteArray::fromRawData((const char*)digest.data(), int(digest.size()))); - }); + QByteArray sig = waitFor(&QCryptoBackend::sign, d->backend, + methodToNID(method), QByteArray::fromRawData((const char*)digest.data(), int(digest.size()))); QCardLock::instance().exclusiveUnlock(); d->backend->logout(); d->smartcard->reload(); // QSmartCard should also know that PIN2 info is updated diff --git a/client/QSmartCard.cpp b/client/QSmartCard.cpp index d9de65978..30717db25 100644 --- a/client/QSmartCard.cpp +++ b/client/QSmartCard.cpp @@ -112,10 +112,8 @@ QPCSCReader::Result Card::transfer(QPCSCReader *reader, bool verify, const QByte if(Common::language() == QLatin1String("en")) language = 0x0409; else if(Common::language() == QLatin1String("et")) language = 0x0425; else if(Common::language() == QLatin1String("ru")) language = 0x0419; - QPCSCReader::Result result; - return waitFor([&]{ - return reader->transferCTL(apdu, verify, language, QSmartCardData::minPinLen(type), newPINOffset, requestCurrentPIN); - }); + return waitFor(&QPCSCReader::transferCTL, reader, + apdu, verify, language, QSmartCardData::minPinLen(type), newPINOffset, requestCurrentPIN); } diff --git a/client/Utils.h b/client/Utils.h index 4bf7053ed..5799a871c 100644 --- a/client/Utils.h +++ b/client/Utils.h @@ -25,14 +25,15 @@ #include namespace { - template - inline auto waitFor(F&& function) { + template + inline auto waitFor(F&& function, Args&& ...args) { std::exception_ptr exception; - typename std::invoke_result::type result{}; + std::invoke_result_t result{}; QEventLoop l; - std::thread([&]{ + // c++20 ... args == std::forward(args) + std::thread([&, function = std::forward(function)]{ try { - result = function(); + result = std::invoke(function, args...); } catch(...) { exception = std::current_exception(); } @@ -44,15 +45,15 @@ namespace { return result; } - template - inline auto dispatchToMain(F&& function) { - typename std::invoke_result::type result{}; + template + inline auto dispatchToMain(F&& function, Args&& ...args) { + std::invoke_result_t result{}; QEventLoop l; QTimer* timer = new QTimer(); timer->moveToThread(qApp->thread()); timer->setSingleShot(true); - QObject::connect(timer, &QTimer::timeout, timer, [&] { - result = function(); + QObject::connect(timer, &QTimer::timeout, timer, [&, function = std::forward(function)] { + result = std::invoke(function, args...); l.exit(); timer->deleteLater(); }); diff --git a/client/dialogs/AccessCert.cpp b/client/dialogs/AccessCert.cpp index 3a4456367..1a353969d 100644 --- a/client/dialogs/AccessCert.cpp +++ b/client/dialogs/AccessCert.cpp @@ -85,7 +85,7 @@ QSslCertificate AccessCert::cert() Application::confValue( Application::PKCS12Pass ).toString() ).certificate(); } -unsigned int AccessCert::count(const QString &date) const +unsigned int AccessCert::count(const QString &date) { return QByteArray::fromBase64(QSettings().value(date).toByteArray()).toUInt(); } @@ -99,7 +99,7 @@ void AccessCert::increment() } } -bool AccessCert::isDefaultCert(const QSslCertificate &cert) const +bool AccessCert::isDefaultCert(const QSslCertificate &cert) { static const QList list { // CN=Riigi Infos\xC3\xBCsteemi Amet, SN = da:98:09:46:6d:57:51:65:48:8b:b2:14:0d:9e:19:27 @@ -115,16 +115,17 @@ bool AccessCert::installCert( const QByteArray &data, const QString &password ) SecExternalFormat format = kSecFormatPKCS12; SecExternalItemType type = kSecItemTypeAggregate; - SecItemImportExportKeyParameters params = {}; - params.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION; - params.flags = kSecKeyImportOnlyOne|kSecKeyNoAccessControl; + SecItemImportExportKeyParameters params{ + SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION, + kSecKeyImportOnlyOne|kSecKeyNoAccessControl, + password.toCFString(), + }; CFTypeRef keyAttributes[] = { kSecAttrIsPermanent, kSecAttrIsExtractable }; params.keyAttributes = CFArrayCreate(nullptr, (const void **)keyAttributes, sizeof(keyAttributes) / sizeof(keyAttributes[0]), nullptr); CFTypeRef keyUsage[] = { kSecAttrCanDecrypt, kSecAttrCanUnwrap, kSecAttrCanDerive }; params.keyUsage = CFArrayCreate(nullptr, (const void **)keyUsage, sizeof(keyUsage) / sizeof(keyUsage[0]), nullptr); - params.passphrase = password.toCFString(); SecKeychainRef keychain; SecKeychainCopyDefault( &keychain ); diff --git a/client/dialogs/AccessCert.h b/client/dialogs/AccessCert.h index a3bb8de29..8fd0229a6 100644 --- a/client/dialogs/AccessCert.h +++ b/client/dialogs/AccessCert.h @@ -33,13 +33,13 @@ class AccessCert final: public WarningDialog bool validate(); static QSslCertificate cert(); - void increment(); + static void increment(); bool installCert( const QByteArray &data, const QString &password ); void remove(); private: - unsigned int count( const QString &date ) const; - bool isDefaultCert( const QSslCertificate &cert ) const; + static unsigned int count(const QString &date); + static bool isDefaultCert(const QSslCertificate &cert); void showWarning( const QString &msg ); class Private; diff --git a/client/dialogs/MobileProgress.cpp b/client/dialogs/MobileProgress.cpp index aaf91965c..76d9f72f0 100644 --- a/client/dialogs/MobileProgress.cpp +++ b/client/dialogs/MobileProgress.cpp @@ -78,7 +78,6 @@ class MobileProgress::Private final: public QDialog, public Ui::MobileProgress #ifdef QT_WIN_EXTRAS QWinTaskbarButton *taskbar = nullptr; #endif - WaitDialogHider hider; }; MobileProgress::MobileProgress(QWidget *parent) @@ -368,6 +367,7 @@ std::vector MobileProgress::sign(const std::string &method, const d->manager->post(d->req, data); d->statusTimer->start(); d->adjustSize(); + WaitDialogHider hider; d->show(); switch(d->l.exec()) { diff --git a/client/dialogs/SmartIDProgress.cpp b/client/dialogs/SmartIDProgress.cpp index 09c501305..415f00b6d 100644 --- a/client/dialogs/SmartIDProgress.cpp +++ b/client/dialogs/SmartIDProgress.cpp @@ -59,6 +59,11 @@ class SmartIDProgress::Private final: public QDialog, public Ui::MobileProgress QString URL() { return !UUID.isNull() && useCustomUUID ? SKURL : PROXYURL; } using QDialog::QDialog; void reject() final { l.exit(QDialog::Rejected); } + void setVisible(bool visible) final { + if(visible && !hider) hider = std::make_unique(); + QDialog::setVisible(visible); + if(!visible && hider) hider.reset(); + } QTimeLine *statusTimer = nullptr; QNetworkAccessManager *manager = nullptr; QNetworkRequest req; @@ -80,7 +85,7 @@ class SmartIDProgress::Private final: public QDialog, public Ui::MobileProgress #ifdef QT_WIN_EXTRAS QWinTaskbarButton *taskbar = nullptr; #endif - WaitDialogHider hider; + std::unique_ptr hider; };