From 73a0f7ddf8a8db0057201374f1518d2063ad9a06 Mon Sep 17 00:00:00 2001 From: saturneric Date: Wed, 16 Apr 2025 01:19:53 +0200 Subject: feat: support key groups --- gpgfrontend.qrc | 1 + resource/lfs/icons/key-group.png | Bin 0 -> 9407 bytes src/core/CMakeLists.txt | 2 +- src/core/function/ArchiveFileOperator.h | 2 +- src/core/function/KeyPackageOperator.cpp | 2 +- src/core/function/KeyPackageOperator.h | 5 +- src/core/function/gpg/GpgAbstractKeyGetter.cpp | 85 ++++++ src/core/function/gpg/GpgAbstractKeyGetter.h | 102 +++++++ src/core/function/gpg/GpgAdvancedOperator.h | 2 +- src/core/function/gpg/GpgAssuanHelper.h | 8 +- src/core/function/gpg/GpgAutomatonHandler.cpp | 6 +- src/core/function/gpg/GpgAutomatonHandler.h | 2 +- src/core/function/gpg/GpgBasicOperator.cpp | 48 ++-- src/core/function/gpg/GpgBasicOperator.h | 16 +- src/core/function/gpg/GpgContext.cpp | 5 + src/core/function/gpg/GpgContext.h | 2 + src/core/function/gpg/GpgFileOpera.cpp | 62 ++-- src/core/function/gpg/GpgFileOpera.h | 41 +-- src/core/function/gpg/GpgKeyGetter.cpp | 49 +++- src/core/function/gpg/GpgKeyGetter.h | 39 ++- src/core/function/gpg/GpgKeyGroupGetter.cpp | 311 +++++++++++++++++++++ src/core/function/gpg/GpgKeyGroupGetter.h | 215 ++++++++++++++ src/core/function/gpg/GpgKeyImportExporter.cpp | 28 +- src/core/function/gpg/GpgKeyImportExporter.h | 10 +- src/core/function/gpg/GpgKeyManager.cpp | 28 +- src/core/function/gpg/GpgKeyManager.h | 17 +- src/core/function/gpg/GpgKeyOpera.cpp | 86 +++--- src/core/function/gpg/GpgKeyOpera.h | 22 +- src/core/function/gpg/GpgUIDOperator.cpp | 22 +- src/core/function/gpg/GpgUIDOperator.h | 10 +- .../result_analyse/GpgVerifyResultAnalyse.h | 1 + src/core/model/DataObject.h | 4 + src/core/model/GpgAbstractKey.h | 17 +- src/core/model/GpgKey.cpp | 4 +- src/core/model/GpgKey.h | 11 +- src/core/model/GpgKeyGroup.cpp | 120 ++++++++ src/core/model/GpgKeyGroup.h | 263 +++++++++++++++++ src/core/model/GpgKeySignature.h | 3 +- src/core/model/GpgKeyTableModel.cpp | 264 ++++++++++------- src/core/model/GpgKeyTableModel.h | 51 ++-- src/core/model/GpgKeyTreeModel.cpp | 11 +- src/core/model/GpgKeyTreeModel.h | 7 + src/core/model/GpgSubKey.cpp | 11 +- src/core/model/GpgSubKey.h | 23 +- src/core/model/GpgUID.h | 3 +- src/core/model/GpgVerifyResult.h | 2 +- src/core/struct/cache_object/KeyGroupCO.h | 86 ++++++ src/core/struct/cache_object/KeyGroupsCO.h | 68 +++++ src/core/typedef/CoreTypedef.h | 4 - src/core/typedef/GpgErrorTypedef.h | 39 +++ src/core/typedef/GpgTypedef.h | 31 +- src/core/utils/GpgUtils.cpp | 78 ++++-- src/core/utils/GpgUtils.h | 35 ++- src/sdk/GFSDKGpg.cpp | 19 +- src/test/core/GpgCoreTestBasicOpera.cpp | 29 +- src/test/core/GpgCoreTestFileBasicOpera.cpp | 45 +-- src/test/core/GpgCoreTestKeyManagement.cpp | 64 ++--- src/test/core/GpgCoreTestKeyOpera.cpp | 20 +- src/test/core/GpgCoreTestKeyUIDOpera.cpp | 28 +- src/test/core/GpgCoreTestKeygen.cpp | 104 +++---- src/test/core/GpgCoreTestSubkeygen.cpp | 36 +-- src/ui/GpgFrontendUIInit.cpp | 2 +- src/ui/UserInterfaceUtils.cpp | 47 +++- src/ui/UserInterfaceUtils.h | 18 +- src/ui/dialog/ADSKsPicker.cpp | 9 +- src/ui/dialog/KeyGroupCreationDialog.cpp | 119 ++++++++ src/ui/dialog/KeyGroupCreationDialog.h | 90 ++++++ src/ui/dialog/KeyGroupManageDialog.cpp | 163 +++++++++++ src/ui/dialog/KeyGroupManageDialog.h | 83 ++++++ src/ui/dialog/SignersPicker.cpp | 14 +- src/ui/dialog/SignersPicker.h | 8 +- .../dialog/controller/SmartCardControllerDialog.h | 1 - .../import_export/ExportKeyPackageDialog.cpp | 26 +- .../dialog/import_export/ExportKeyPackageDialog.h | 6 +- .../dialog/import_export/KeyImportDetailDialog.cpp | 1 - src/ui/dialog/import_export/KeyUploadDialog.cpp | 14 +- src/ui/dialog/import_export/KeyUploadDialog.h | 6 +- .../dialog/key_generate/SubkeyGenerateDialog.cpp | 9 +- src/ui/dialog/key_generate/SubkeyGenerateDialog.h | 5 +- src/ui/dialog/keypair_details/KeyDetailsDialog.cpp | 23 +- src/ui/dialog/keypair_details/KeyDetailsDialog.h | 2 +- src/ui/dialog/keypair_details/KeyNewUIDDialog.cpp | 14 +- src/ui/dialog/keypair_details/KeyNewUIDDialog.h | 6 +- src/ui/dialog/keypair_details/KeyPairDetailTab.cpp | 76 +++-- src/ui/dialog/keypair_details/KeyPairDetailTab.h | 5 +- src/ui/dialog/keypair_details/KeyPairOperaTab.cpp | 101 ++++--- src/ui/dialog/keypair_details/KeyPairOperaTab.h | 7 +- src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp | 43 ++- src/ui/dialog/keypair_details/KeyPairSubkeyTab.h | 4 +- src/ui/dialog/keypair_details/KeyPairUIDTab.cpp | 27 +- src/ui/dialog/keypair_details/KeyPairUIDTab.h | 4 +- .../keypair_details/KeySetExpireDateDialog.cpp | 25 +- .../keypair_details/KeySetExpireDateDialog.h | 6 +- src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp | 24 +- src/ui/dialog/keypair_details/KeyUIDSignDialog.h | 6 +- src/ui/function/SetOwnerTrustLevel.cpp | 13 +- src/ui/function/SetOwnerTrustLevel.h | 3 +- src/ui/main_window/KeyMgmt.cpp | 197 ++++++------- src/ui/main_window/KeyMgmt.h | 50 ++-- src/ui/main_window/MainWindow.cpp | 5 +- src/ui/main_window/MainWindow.h | 13 +- src/ui/main_window/MainWindowGpgOperaFunction.cpp | 49 ++-- src/ui/main_window/MainWindowSlotFunction.cpp | 145 +++++----- src/ui/main_window/MainWindowSlotUI.cpp | 41 ++- src/ui/main_window/MainWindowUI.cpp | 32 ++- src/ui/model/GpgKeyTableProxyModel.cpp | 43 +-- src/ui/model/GpgKeyTableProxyModel.h | 4 +- src/ui/model/GpgKeyTreeProxyModel.cpp | 3 +- src/ui/struct/GpgOperaResultContext.h | 4 +- src/ui/widgets/KeyList.cpp | 249 +++++++++-------- src/ui/widgets/KeyList.h | 140 ++++++---- src/ui/widgets/KeyTable.cpp | 64 +++-- src/ui/widgets/KeyTable.h | 44 +-- src/ui/widgets/KeyTreeView.cpp | 26 +- src/ui/widgets/KeyTreeView.h | 8 + src/ui/widgets/VerifyKeyDetailBox.cpp | 23 +- src/ui/widgets/VerifyKeyDetailBox.h | 2 +- ui/KeyGroupManageDialog.ui | 121 ++++++++ ui/KeyList.ui | 11 + 119 files changed, 3616 insertions(+), 1377 deletions(-) create mode 100644 resource/lfs/icons/key-group.png create mode 100644 src/core/function/gpg/GpgAbstractKeyGetter.cpp create mode 100644 src/core/function/gpg/GpgAbstractKeyGetter.h create mode 100644 src/core/function/gpg/GpgKeyGroupGetter.cpp create mode 100644 src/core/function/gpg/GpgKeyGroupGetter.h create mode 100644 src/core/model/GpgKeyGroup.cpp create mode 100644 src/core/model/GpgKeyGroup.h create mode 100644 src/core/struct/cache_object/KeyGroupCO.h create mode 100644 src/core/struct/cache_object/KeyGroupsCO.h create mode 100644 src/core/typedef/GpgErrorTypedef.h create mode 100644 src/ui/dialog/KeyGroupCreationDialog.cpp create mode 100644 src/ui/dialog/KeyGroupCreationDialog.h create mode 100644 src/ui/dialog/KeyGroupManageDialog.cpp create mode 100644 src/ui/dialog/KeyGroupManageDialog.h create mode 100644 ui/KeyGroupManageDialog.ui diff --git a/gpgfrontend.qrc b/gpgfrontend.qrc index 4f1e2275..67656e39 100644 --- a/gpgfrontend.qrc +++ b/gpgfrontend.qrc @@ -112,6 +112,7 @@ resource/lfs/icons/encr-sign.png resource/lfs/icons/decr-verify.png resource/lfs/icons/smart-card.png + resource/lfs/icons/key-group.png resource/lfs/test/data/pv1.key diff --git a/resource/lfs/icons/key-group.png b/resource/lfs/icons/key-group.png new file mode 100644 index 00000000..9a412ab9 Binary files /dev/null and b/resource/lfs/icons/key-group.png differ diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 5a1c9477..c60bdac3 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -81,7 +81,7 @@ target_include_directories(gpgfrontend_core PRIVATE ${LibArchive_INCLUDE_DIR}) target_link_libraries(gpgfrontend_core PRIVATE archive) # link qt -target_link_libraries(gpgfrontend_core PUBLIC Qt::Core) +target_link_libraries(gpgfrontend_core PUBLIC Qt::Core Qt::Gui) # set up pch target_precompile_headers(gpgfrontend_core diff --git a/src/core/function/ArchiveFileOperator.h b/src/core/function/ArchiveFileOperator.h index ace16d2b..eedbeca6 100644 --- a/src/core/function/ArchiveFileOperator.h +++ b/src/core/function/ArchiveFileOperator.h @@ -29,8 +29,8 @@ #pragma once #include "core/GpgFrontendCore.h" +#include "core/model/DataObject.h" #include "core/model/GFDataExchanger.h" -#include "core/typedef/CoreTypedef.h" #include "core/utils/IOUtils.h" namespace GpgFrontend { diff --git a/src/core/function/KeyPackageOperator.cpp b/src/core/function/KeyPackageOperator.cpp index a5f1989c..b71642f9 100644 --- a/src/core/function/KeyPackageOperator.cpp +++ b/src/core/function/KeyPackageOperator.cpp @@ -52,7 +52,7 @@ auto KeyPackageOperator::GeneratePassphrase(const QString& phrase_path, void KeyPackageOperator::GenerateKeyPackage(const QString& key_package_path, const QString& key_package_name, int channel, - const KeyArgsList& keys, + const GpgAbstractKeyPtrList& keys, QString& phrase, bool secret, const OperationCallback& cb) { GpgKeyImportExporter::GetInstance(channel).ExportAllKeys( diff --git a/src/core/function/KeyPackageOperator.h b/src/core/function/KeyPackageOperator.h index 82bb65c1..d8c87dd1 100644 --- a/src/core/function/KeyPackageOperator.h +++ b/src/core/function/KeyPackageOperator.h @@ -70,8 +70,9 @@ class GPGFRONTEND_CORE_EXPORT KeyPackageOperator { */ static void GenerateKeyPackage(const QString &key_package_path, const QString &key_package_name, int channel, - const KeyArgsList &keys, QString &phrase, - bool secret, const OperationCallback &cb); + const GpgAbstractKeyPtrList &keys, + QString &phrase, bool secret, + const OperationCallback &cb); /** * @brief import key package diff --git a/src/core/function/gpg/GpgAbstractKeyGetter.cpp b/src/core/function/gpg/GpgAbstractKeyGetter.cpp new file mode 100644 index 00000000..0b544469 --- /dev/null +++ b/src/core/function/gpg/GpgAbstractKeyGetter.cpp @@ -0,0 +1,85 @@ +/** + * Copyright (C) 2021-2024 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend 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 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend 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 GpgFrontend. If not, see . + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "GpgAbstractKeyGetter.h" + +#include "core/model/GpgKeyTableModel.h" +#include "core/utils/GpgUtils.h" + +namespace GpgFrontend { + +GpgAbstractKeyGetter::GpgAbstractKeyGetter(int channel) + : SingletonFunctionObject(channel){}; + +auto GpgAbstractKeyGetter::Fetch() -> GpgAbstractKeyPtrList { + auto ret = GpgAbstractKeyPtrList{}; + + auto keys = key_.Fetch(); + for (const auto& key : keys) { + ret.push_back(qSharedPointerCast(key)); + } + + auto kgs = kg_.Fetch(); + for (const auto& kg : kgs) { + ret.push_back(qSharedPointerCast(kg)); + } + + return ret; +} + +auto GpgAbstractKeyGetter::GetGpgKeyTableModel() + -> QSharedPointer { + return SecureCreateQSharedObject( + SingletonFunctionObject::GetChannel(), Fetch(), nullptr); +} + +auto GpgAbstractKeyGetter::FlushCache() -> bool { + return key_.FlushKeyCache() && kg_.FlushCache(); +} + +auto GpgAbstractKeyGetter::GetKey(const QString& key_id) -> GpgAbstractKeyPtr { + if (IsKeyGroupID(key_id)) { + return kg_.KeyGroup(key_id); + } + return key_.GetKeyPtr(key_id); +} + +auto GpgAbstractKeyGetter::GetKeys(const QStringList& key_ids) + -> GpgAbstractKeyPtrList { + auto ret = GpgAbstractKeyPtrList{}; + for (const auto& key_id : key_ids) { + auto key = GetKey(key_id); + if (key == nullptr) continue; + + ret.push_back(key); + } + return ret; +} + +GpgAbstractKeyGetter::~GpgAbstractKeyGetter() = default; +} // namespace GpgFrontend \ No newline at end of file diff --git a/src/core/function/gpg/GpgAbstractKeyGetter.h b/src/core/function/gpg/GpgAbstractKeyGetter.h new file mode 100644 index 00000000..571121a9 --- /dev/null +++ b/src/core/function/gpg/GpgAbstractKeyGetter.h @@ -0,0 +1,102 @@ +/** + * Copyright (C) 2021-2024 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend 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 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend 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 GpgFrontend. If not, see . + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#pragma once + +#include "core/function/basic/GpgFunctionObject.h" +#include "core/function/gpg/GpgKeyGetter.h" +#include "core/function/gpg/GpgKeyGroupGetter.h" +#include "core/typedef/GpgTypedef.h" + +namespace GpgFrontend { + +class GpgKeyTableModel; + +/** + * @brief + * + */ +class GPGFRONTEND_CORE_EXPORT GpgAbstractKeyGetter + : public SingletonFunctionObject { + public: + /** + * @brief Construct a new Gpg Key Getter object + * + * @param channel + */ + explicit GpgAbstractKeyGetter(int channel = kGpgFrontendDefaultChannel); + + /** + * @brief Destroy the Gpg Key Getter object + * + */ + ~GpgAbstractKeyGetter(); + + /** + * @brief Get the Key object + * + * @param fpr + * @return GpgKey + */ + auto GetKey(const QString& key_id) -> GpgAbstractKeyPtr; + + /** + * @brief Get the Keys object + * + * @param key_ids + * @return auto + */ + auto GetKeys(const QStringList& key_ids) -> GpgAbstractKeyPtrList; + + /** + * @brief Get all the keys by receiving a linked list + * + * @return KeyLinkListPtr + */ + auto Fetch() -> GpgAbstractKeyPtrList; + + /** + * @brief flush the keys in the cache + * + */ + auto FlushCache() -> bool; + + /** + * @brief + * + * @return GpgKeyTableModel + */ + auto GetGpgKeyTableModel() -> QSharedPointer; + + private: + GpgKeyGetter& key_ = + GpgKeyGetter::GetInstance(SingletonFunctionObject::GetChannel()); + GpgKeyGroupGetter& kg_ = + GpgKeyGroupGetter::GetInstance(SingletonFunctionObject::GetChannel()); +}; +} // namespace GpgFrontend diff --git a/src/core/function/gpg/GpgAdvancedOperator.h b/src/core/function/gpg/GpgAdvancedOperator.h index cfd5fbcf..57279adb 100644 --- a/src/core/function/gpg/GpgAdvancedOperator.h +++ b/src/core/function/gpg/GpgAdvancedOperator.h @@ -32,7 +32,7 @@ #pragma once -#include "core/typedef/CoreTypedef.h" +#include "core/model/DataObject.h" namespace GpgFrontend { diff --git a/src/core/function/gpg/GpgAssuanHelper.h b/src/core/function/gpg/GpgAssuanHelper.h index 6e58e27c..a0c45d7a 100644 --- a/src/core/function/gpg/GpgAssuanHelper.h +++ b/src/core/function/gpg/GpgAssuanHelper.h @@ -113,6 +113,10 @@ class GPGFRONTEND_CORE_EXPORT GpgAssuanHelper GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); QMap assuan_ctx_; + QByteArray temp_data_; + QString temp_status_; + QString gpgconf_path_; + /** * @brief * @@ -169,10 +173,6 @@ class GPGFRONTEND_CORE_EXPORT GpgAssuanHelper */ static auto default_inquery_callback(void* opaque, const char* inquery) -> gpgme_error_t; - - QByteArray temp_data_; - QString temp_status_; - QString gpgconf_path_; }; }; // namespace GpgFrontend \ No newline at end of file diff --git a/src/core/function/gpg/GpgAutomatonHandler.cpp b/src/core/function/gpg/GpgAutomatonHandler.cpp index af2f0cba..b2d9d562 100644 --- a/src/core/function/gpg/GpgAutomatonHandler.cpp +++ b/src/core/function/gpg/GpgAutomatonHandler.cpp @@ -97,13 +97,13 @@ auto GpgAutomatonHandler::interator_cb_func(void* handle, const char* status, } auto GpgAutomatonHandler::DoInteract( - const GpgKey& key, AutomatonNextStateHandler next_state_handler, + const GpgKeyPtr& key, AutomatonNextStateHandler next_state_handler, AutomatonActionHandler action_handler, int flags) -> bool { gpgme_key_t p_key = - flags == GPGME_INTERACT_CARD ? nullptr : static_cast(key); + flags == GPGME_INTERACT_CARD ? nullptr : static_cast(*key); AutomatonHandelStruct handel_struct( - flags == GPGME_INTERACT_CARD ? "" : key.Fingerprint()); + flags == GPGME_INTERACT_CARD ? "" : key->Fingerprint()); handel_struct.SetHandler(std::move(next_state_handler), std::move(action_handler)); diff --git a/src/core/function/gpg/GpgAutomatonHandler.h b/src/core/function/gpg/GpgAutomatonHandler.h index f86299e8..cdf96060 100644 --- a/src/core/function/gpg/GpgAutomatonHandler.h +++ b/src/core/function/gpg/GpgAutomatonHandler.h @@ -97,7 +97,7 @@ class GpgAutomatonHandler * @return true * @return false */ - auto DoInteract(const GpgKey& key, + auto DoInteract(const GpgKeyPtr& key, AutomatonNextStateHandler next_state_handler, AutomatonActionHandler action_handler, int flags = 0) -> bool; diff --git a/src/core/function/gpg/GpgBasicOperator.cpp b/src/core/function/gpg/GpgBasicOperator.cpp index 2548409e..43917db3 100644 --- a/src/core/function/gpg/GpgBasicOperator.cpp +++ b/src/core/function/gpg/GpgBasicOperator.cpp @@ -43,15 +43,17 @@ namespace GpgFrontend { GpgBasicOperator::GpgBasicOperator(int channel) : SingletonFunctionObject(channel) {} -void SetSignersImpl(GpgContext& ctx_, const KeyArgsList& signers, bool ascii) { +void SetSignersImpl(GpgContext& ctx_, const GpgAbstractKeyPtrList& signers, + bool ascii) { auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext(); gpgme_signers_clear(ctx); - for (const GpgKey& key : signers) { - LOG_D() << "signer's key fpr: " << key.Fingerprint(); - if (key.IsHasActualSignCap()) { - auto error = gpgme_signers_add(ctx, gpgme_key_t(key)); + auto keys = ConvertKey2GpgKeyList(ctx_.GetChannel(), signers); + for (const auto& key : keys) { + LOG_D() << "signer's key fpr: " << key->Fingerprint(); + if (key->IsHasSignCap()) { + auto error = gpgme_signers_add(ctx, static_cast(*key)); CheckGpgError(error); } } @@ -62,10 +64,10 @@ void SetSignersImpl(GpgContext& ctx_, const KeyArgsList& signers, bool ascii) { } } -auto EncryptImpl(GpgContext& ctx_, const KeyArgsList& keys, +auto EncryptImpl(GpgContext& ctx_, const GpgAbstractKeyPtrList& keys, const GFBuffer& in_buffer, bool ascii, const DataObjectPtr& data_object) -> GpgError { - auto recipients = Convert2RawGpgMEKeyList(keys); + auto recipients = Convert2RawGpgMEKeyList(ctx_.GetChannel(), keys); GpgData data_in(in_buffer); GpgData data_out; @@ -82,7 +84,7 @@ auto EncryptImpl(GpgContext& ctx_, const KeyArgsList& keys, return err; } -void GpgBasicOperator::Encrypt(const KeyArgsList& keys, +void GpgBasicOperator::Encrypt(const GpgAbstractKeyPtrList& keys, const GFBuffer& in_buffer, bool ascii, const GpgOperationCallback& cb) { RunGpgOperaAsync( @@ -92,7 +94,7 @@ void GpgBasicOperator::Encrypt(const KeyArgsList& keys, cb, "gpgme_op_encrypt", "2.1.0"); } -auto GpgBasicOperator::EncryptSync(const KeyArgsList& keys, +auto GpgBasicOperator::EncryptSync(const GpgAbstractKeyPtrList& keys, const GFBuffer& in_buffer, bool ascii) -> std::tuple { return RunGpgOperaSync( @@ -199,7 +201,7 @@ auto GpgBasicOperator::VerifySync(const GFBuffer& in_buffer, "gpgme_op_verify", "2.1.0"); } -auto SignImpl(GpgContext& ctx_, const KeyArgsList& signers, +auto SignImpl(GpgContext& ctx_, const GpgAbstractKeyPtrList& signers, const GFBuffer& in_buffer, GpgSignMode mode, bool ascii, const DataObjectPtr& data_object) -> GpgError { if (signers.empty()) return GPG_ERR_CANCELED; @@ -222,7 +224,7 @@ auto SignImpl(GpgContext& ctx_, const KeyArgsList& signers, return err; } -void GpgBasicOperator::Sign(const KeyArgsList& signers, +void GpgBasicOperator::Sign(const GpgAbstractKeyPtrList& signers, const GFBuffer& in_buffer, GpgSignMode mode, bool ascii, const GpgOperationCallback& cb) { RunGpgOperaAsync( @@ -233,8 +235,8 @@ void GpgBasicOperator::Sign(const KeyArgsList& signers, } auto GpgBasicOperator::SignSync( - const KeyArgsList& signers, const GFBuffer& in_buffer, GpgSignMode mode, - bool ascii) -> std::tuple { + const GpgAbstractKeyPtrList& signers, const GFBuffer& in_buffer, + GpgSignMode mode, bool ascii) -> std::tuple { return RunGpgOperaSync( [=](const DataObjectPtr& data_object) { return SignImpl(ctx_, signers, in_buffer, mode, ascii, data_object); @@ -279,13 +281,14 @@ auto GpgBasicOperator::DecryptVerifySync(const GFBuffer& in_buffer) "gpgme_op_decrypt_verify", "2.1.0"); } -auto EncryptSignImpl(GpgContext& ctx_, const KeyArgsList& keys, - const KeyArgsList& signers, const GFBuffer& in_buffer, - bool ascii, const DataObjectPtr& data_object) -> GpgError { +auto EncryptSignImpl(GpgContext& ctx_, const GpgAbstractKeyPtrList& keys, + const GpgAbstractKeyPtrList& signers, + const GFBuffer& in_buffer, bool ascii, + const DataObjectPtr& data_object) -> GpgError { if (keys.empty() || signers.empty()) return GPG_ERR_CANCELED; GpgError err; - QContainer recipients(keys.begin(), keys.end()); + auto recipients = Convert2RawGpgMEKeyList(ctx_.GetChannel(), keys); // Last entry data_in array has to be nullptr recipients.push_back(nullptr); @@ -307,8 +310,8 @@ auto EncryptSignImpl(GpgContext& ctx_, const KeyArgsList& keys, return err; } -void GpgBasicOperator::EncryptSign(const KeyArgsList& keys, - const KeyArgsList& signers, +void GpgBasicOperator::EncryptSign(const GpgAbstractKeyPtrList& keys, + const GpgAbstractKeyPtrList& signers, const GFBuffer& in_buffer, bool ascii, const GpgOperationCallback& cb) { RunGpgOperaAsync( @@ -319,8 +322,8 @@ void GpgBasicOperator::EncryptSign(const KeyArgsList& keys, cb, "gpgme_op_encrypt_sign", "2.1.0"); } -auto GpgBasicOperator::EncryptSignSync(const KeyArgsList& keys, - const KeyArgsList& signers, +auto GpgBasicOperator::EncryptSignSync(const GpgAbstractKeyPtrList& keys, + const GpgAbstractKeyPtrList& signers, const GFBuffer& in_buffer, bool ascii) -> std::tuple { return RunGpgOperaSync( @@ -331,7 +334,8 @@ auto GpgBasicOperator::EncryptSignSync(const KeyArgsList& keys, "gpgme_op_encrypt_sign", "2.1.0"); } -void GpgBasicOperator::SetSigners(const KeyArgsList& signers, bool ascii) { +void GpgBasicOperator::SetSigners(const GpgAbstractKeyPtrList& signers, + bool ascii) { SetSignersImpl(ctx_, signers, ascii); } diff --git a/src/core/function/gpg/GpgBasicOperator.h b/src/core/function/gpg/GpgBasicOperator.h index 990d7af5..ac6908f4 100644 --- a/src/core/function/gpg/GpgBasicOperator.h +++ b/src/core/function/gpg/GpgBasicOperator.h @@ -56,14 +56,14 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator * @brief * */ - void Encrypt(const KeyArgsList&, const GFBuffer&, bool, + void Encrypt(const GpgAbstractKeyPtrList&, const GFBuffer&, bool, const GpgOperationCallback&); /** * @brief * */ - auto EncryptSync(const KeyArgsList&, const GFBuffer&, + auto EncryptSync(const GpgAbstractKeyPtrList&, const GFBuffer&, bool) -> std::tuple; /** @@ -99,7 +99,8 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator * @param ascii ascii mode * @return */ - void EncryptSign(const KeyArgsList& keys, const KeyArgsList& signers, + void EncryptSign(const GpgAbstractKeyPtrList& keys, + const GpgAbstractKeyPtrList& signers, const GFBuffer& in_buffer, bool ascii, const GpgOperationCallback& cb); @@ -112,7 +113,8 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator * @param ascii * @param cb */ - auto EncryptSignSync(const KeyArgsList& keys, const KeyArgsList& signers, + auto EncryptSignSync(const GpgAbstractKeyPtrList& keys, + const GpgAbstractKeyPtrList& signers, const GFBuffer& in_buffer, bool ascii) -> std::tuple; @@ -196,7 +198,7 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator * @param result the result of the operation * @return error code */ - void Sign(const KeyArgsList& signers, const GFBuffer& in_buffer, + void Sign(const GpgAbstractKeyPtrList& signers, const GFBuffer& in_buffer, GpgSignMode mode, bool ascii, const GpgOperationCallback& cb); /** @@ -209,7 +211,7 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator * @param cb * @return std::tuple */ - auto SignSync(const KeyArgsList& signers, const GFBuffer& in_buffer, + auto SignSync(const GpgAbstractKeyPtrList& signers, const GFBuffer& in_buffer, GpgSignMode mode, bool ascii) -> std::tuple; @@ -219,7 +221,7 @@ class GPGFRONTEND_CORE_EXPORT GpgBasicOperator * * @param keys */ - void SetSigners(const KeyArgsList& signers, bool ascii); + void SetSigners(const GpgAbstractKeyPtrList& signers, bool ascii); /** * @brief Get a global signature private keys that has been set. diff --git a/src/core/function/gpg/GpgContext.cpp b/src/core/function/gpg/GpgContext.cpp index 88eb3c1b..de450356 100644 --- a/src/core/function/gpg/GpgContext.cpp +++ b/src/core/function/gpg/GpgContext.cpp @@ -189,6 +189,8 @@ class GpgContext::Impl { return component_dirs_.value(component_type_to_q_string(type), ""); } + [[nodiscard]] auto KeyDBName() const -> QString { return db_name_; } + private: GpgContext *parent_; GpgContextInitArgs args_{}; ///< @@ -199,6 +201,7 @@ class GpgContext::Impl { std::mutex ctx_ref_lock_; std::mutex binary_ctx_ref_lock_; + QString db_name_; QString gpgconf_path_; QString database_path_; QMap component_dirs_; @@ -250,6 +253,7 @@ class GpgContext::Impl { // set custom gpg key db path if (!args_.db_path.isEmpty()) { database_path_ = args_.db_path; + db_name_ = args_.db_name; } LOG_D() << "ctx set engine info, channel: " << parent_->GetChannel() @@ -445,4 +449,5 @@ auto GpgContext::ComponentDirectory(GpgComponentType type) const -> QString { return p_->ComponentDirectories(type); } +auto GpgContext::KeyDBName() const -> QString { return p_->KeyDBName(); } } // namespace GpgFrontend \ No newline at end of file diff --git a/src/core/function/gpg/GpgContext.h b/src/core/function/gpg/GpgContext.h index 4c683c0b..350c153e 100644 --- a/src/core/function/gpg/GpgContext.h +++ b/src/core/function/gpg/GpgContext.h @@ -71,6 +71,8 @@ class GPGFRONTEND_CORE_EXPORT GpgContext auto DefaultContext() -> gpgme_ctx_t; + [[nodiscard]] auto KeyDBName() const -> QString; + [[nodiscard]] auto HomeDirectory() const -> QString; [[nodiscard]] auto ComponentDirectory(GpgComponentType) const -> QString; diff --git a/src/core/function/gpg/GpgFileOpera.cpp b/src/core/function/gpg/GpgFileOpera.cpp index a3ad1ac5..334aae6f 100644 --- a/src/core/function/gpg/GpgFileOpera.cpp +++ b/src/core/function/gpg/GpgFileOpera.cpp @@ -66,10 +66,10 @@ void CreateArchiveHelper(const QString& in_path, GpgFileOpera::GpgFileOpera(int channel) : SingletonFunctionObject(channel) {} -auto EncryptFileGpgDataImpl(GpgContext& ctx_, const KeyArgsList& keys, +auto EncryptFileGpgDataImpl(GpgContext& ctx_, const GpgAbstractKeyPtrList& keys, GpgData& data_in, bool ascii, GpgData& data_out, const DataObjectPtr& data_object) -> GpgError { - auto recipients = Convert2RawGpgMEKeyList(keys); + auto recipients = Convert2RawGpgMEKeyList(ctx_.GetChannel(), keys); auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext(); auto err = CheckGpgError( @@ -79,7 +79,7 @@ auto EncryptFileGpgDataImpl(GpgContext& ctx_, const KeyArgsList& keys, return err; } -auto EncryptFileImpl(GpgContext& ctx_, const KeyArgsList& keys, +auto EncryptFileImpl(GpgContext& ctx_, const GpgAbstractKeyPtrList& keys, const QString& in_path, bool ascii, const QString& out_path, const DataObjectPtr& data_object) -> GpgError { @@ -90,8 +90,9 @@ auto EncryptFileImpl(GpgContext& ctx_, const KeyArgsList& keys, data_object); } -void GpgFileOpera::EncryptFile(const KeyArgsList& keys, const QString& in_path, - bool ascii, const QString& out_path, +void GpgFileOpera::EncryptFile(const GpgAbstractKeyPtrList& keys, + const QString& in_path, bool ascii, + const QString& out_path, const GpgOperationCallback& cb) { RunGpgOperaAsync( [=](const DataObjectPtr& data_object) { @@ -102,7 +103,7 @@ void GpgFileOpera::EncryptFile(const KeyArgsList& keys, const QString& in_path, } auto GpgFileOpera::EncryptFileSync( - const KeyArgsList& keys, const QString& in_path, bool ascii, + const GpgAbstractKeyPtrList& keys, const QString& in_path, bool ascii, const QString& out_path) -> std::tuple { return RunGpgOperaSync( [=](const DataObjectPtr& data_object) { @@ -112,7 +113,7 @@ auto GpgFileOpera::EncryptFileSync( "gpgme_op_encrypt", "2.1.0"); } -void GpgFileOpera::EncryptDirectory(const KeyArgsList& keys, +void GpgFileOpera::EncryptDirectory(const GpgAbstractKeyPtrList& keys, const QString& in_path, bool ascii, const QString& out_path, const GpgOperationCallback& cb) { @@ -186,8 +187,8 @@ void GpgFileOpera::DecryptArchive(const QString& in_path, } auto SignFileGpgDataImpl(GpgContext& ctx_, GpgBasicOperator& basic_opera_, - const KeyArgsList& keys, GpgData& data_in, bool ascii, - GpgData& data_out, + const GpgAbstractKeyPtrList& keys, GpgData& data_in, + bool ascii, GpgData& data_out, const DataObjectPtr& data_object) -> GpgError { GpgError err; @@ -205,8 +206,8 @@ auto SignFileGpgDataImpl(GpgContext& ctx_, GpgBasicOperator& basic_opera_, } auto SignFileImpl(GpgContext& ctx_, GpgBasicOperator& basic_opera_, - const KeyArgsList& keys, const QString& in_path, bool ascii, - const QString& out_path, + const GpgAbstractKeyPtrList& keys, const QString& in_path, + bool ascii, const QString& out_path, const DataObjectPtr& data_object) -> GpgError { GpgData data_in(in_path, true); GpgData data_out(out_path, false); @@ -215,8 +216,9 @@ auto SignFileImpl(GpgContext& ctx_, GpgBasicOperator& basic_opera_, data_object); } -void GpgFileOpera::SignFile(const KeyArgsList& keys, const QString& in_path, - bool ascii, const QString& out_path, +void GpgFileOpera::SignFile(const GpgAbstractKeyPtrList& keys, + const QString& in_path, bool ascii, + const QString& out_path, const GpgOperationCallback& cb) { RunGpgOperaAsync( [=](const DataObjectPtr& data_object) { @@ -226,9 +228,9 @@ void GpgFileOpera::SignFile(const KeyArgsList& keys, const QString& in_path, cb, "gpgme_op_sign", "2.1.0"); } -auto GpgFileOpera::SignFileSync(const KeyArgsList& keys, const QString& in_path, - bool ascii, const QString& out_path) - -> std::tuple { +auto GpgFileOpera::SignFileSync( + const GpgAbstractKeyPtrList& keys, const QString& in_path, bool ascii, + const QString& out_path) -> std::tuple { return RunGpgOperaSync( [=](const DataObjectPtr& data_object) { return SignFileImpl(ctx_, basic_opera_, keys, in_path, ascii, out_path, @@ -282,12 +284,12 @@ auto GpgFileOpera::VerifyFileSync(const QString& data_path, auto EncryptSignFileGpgDataImpl(GpgContext& ctx_, GpgBasicOperator& basic_opera_, - const KeyArgsList& keys, - const KeyArgsList& signer_keys, + const GpgAbstractKeyPtrList& keys, + const GpgAbstractKeyPtrList& signer_keys, GpgData& data_in, bool ascii, GpgData& data_out, const DataObjectPtr& data_object) -> GpgError { GpgError err; - auto recipients = Convert2RawGpgMEKeyList(keys); + auto recipients = Convert2RawGpgMEKeyList(ctx_.GetChannel(), keys); basic_opera_.SetSigners(signer_keys, ascii); @@ -304,9 +306,10 @@ auto EncryptSignFileGpgDataImpl(GpgContext& ctx_, } auto EncryptSignFileImpl(GpgContext& ctx_, GpgBasicOperator& basic_opera_, - const KeyArgsList& keys, - const KeyArgsList& signer_keys, const QString& in_path, - bool ascii, const QString& out_path, + const GpgAbstractKeyPtrList& keys, + const GpgAbstractKeyPtrList& signer_keys, + const QString& in_path, bool ascii, + const QString& out_path, const DataObjectPtr& data_object) -> GpgError { GpgData data_in(in_path, true); GpgData data_out(out_path, false); @@ -315,8 +318,8 @@ auto EncryptSignFileImpl(GpgContext& ctx_, GpgBasicOperator& basic_opera_, data_in, ascii, data_out, data_object); } -void GpgFileOpera::EncryptSignFile(const KeyArgsList& keys, - const KeyArgsList& signer_keys, +void GpgFileOpera::EncryptSignFile(const GpgAbstractKeyPtrList& keys, + const GpgAbstractKeyPtrList& signer_keys, const QString& in_path, bool ascii, const QString& out_path, const GpgOperationCallback& cb) { @@ -329,7 +332,7 @@ void GpgFileOpera::EncryptSignFile(const KeyArgsList& keys, } auto GpgFileOpera::EncryptSignFileSync( - const KeyArgsList& keys, const KeyArgsList& signer_keys, + const GpgAbstractKeyPtrList& keys, const GpgAbstractKeyPtrList& signer_keys, const QString& in_path, bool ascii, const QString& out_path) -> std::tuple { return RunGpgOperaSync( @@ -340,11 +343,10 @@ auto GpgFileOpera::EncryptSignFileSync( "gpgme_op_encrypt_sign", "2.1.0"); } -void GpgFileOpera::EncryptSignDirectory(const KeyArgsList& keys, - const KeyArgsList& signer_keys, - const QString& in_path, bool ascii, - const QString& out_path, - const GpgOperationCallback& cb) { +void GpgFileOpera::EncryptSignDirectory( + const GpgAbstractKeyPtrList& keys, const GpgAbstractKeyPtrList& signer_keys, + const QString& in_path, bool ascii, const QString& out_path, + const GpgOperationCallback& cb) { auto ex = CreateStandardGFDataExchanger(); RunGpgOperaAsync( diff --git a/src/core/function/gpg/GpgFileOpera.h b/src/core/function/gpg/GpgFileOpera.h index 5119bb36..4cbe70d2 100644 --- a/src/core/function/gpg/GpgFileOpera.h +++ b/src/core/function/gpg/GpgFileOpera.h @@ -61,8 +61,9 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera * @param channel Channel in context * @return unsigned int error code */ - void EncryptFile(const KeyArgsList& keys, const QString& in_path, bool ascii, - const QString& out_path, const GpgOperationCallback& cb); + void EncryptFile(const GpgAbstractKeyPtrList& keys, const QString& in_path, + bool ascii, const QString& out_path, + const GpgOperationCallback& cb); /** * @brief @@ -73,9 +74,9 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera * @param out_path * @return std::tuple */ - auto EncryptFileSync(const KeyArgsList& keys, const QString& in_path, - bool ascii, const QString& out_path) - -> std::tuple; + auto EncryptFileSync( + const GpgAbstractKeyPtrList& keys, const QString& in_path, bool ascii, + const QString& out_path) -> std::tuple; /** * @brief @@ -86,8 +87,9 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera * @param out_path * @param cb */ - void EncryptDirectory(const KeyArgsList& keys, const QString& in_path, - bool ascii, const QString& out_path, + void EncryptDirectory(const GpgAbstractKeyPtrList& keys, + const QString& in_path, bool ascii, + const QString& out_path, const GpgOperationCallback& cb); /** @@ -180,8 +182,9 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera * @param channel * @return GpgError */ - void SignFile(const KeyArgsList& keys, const QString& in_path, bool ascii, - const QString& out_path, const GpgOperationCallback& cb); + void SignFile(const GpgAbstractKeyPtrList& keys, const QString& in_path, + bool ascii, const QString& out_path, + const GpgOperationCallback& cb); /** * @brief @@ -192,8 +195,8 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera * @param out_path * @return std::tuple */ - auto SignFileSync(const KeyArgsList& keys, const QString& in_path, bool ascii, - const QString& out_path) + auto SignFileSync(const GpgAbstractKeyPtrList& keys, const QString& in_path, + bool ascii, const QString& out_path) -> std::tuple; /** @@ -228,7 +231,8 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera * @param out_path * @param cb */ - void EncryptSignFile(const KeyArgsList& keys, const KeyArgsList& signer_keys, + void EncryptSignFile(const GpgAbstractKeyPtrList& keys, + const GpgAbstractKeyPtrList& signer_keys, const QString& in_path, bool ascii, const QString& out_path, const GpgOperationCallback& cb); @@ -241,10 +245,11 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera * @param ascii * @param out_path */ - auto EncryptSignFileSync( - const KeyArgsList& keys, const KeyArgsList& signer_keys, - const QString& in_path, bool ascii, - const QString& out_path) -> std::tuple; + auto EncryptSignFileSync(const GpgAbstractKeyPtrList& keys, + const GpgAbstractKeyPtrList& signer_keys, + const QString& in_path, bool ascii, + const QString& out_path) + -> std::tuple; /** * @brief @@ -256,8 +261,8 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera * @param out_path * @param cb */ - void EncryptSignDirectory(const KeyArgsList& keys, - const KeyArgsList& signer_keys, + void EncryptSignDirectory(const GpgAbstractKeyPtrList& keys, + const GpgAbstractKeyPtrList& signer_keys, const QString& in_path, bool ascii, const QString& out_path, const GpgOperationCallback& cb); diff --git a/src/core/function/gpg/GpgKeyGetter.cpp b/src/core/function/gpg/GpgKeyGetter.cpp index 14145f7f..86218a94 100644 --- a/src/core/function/gpg/GpgKeyGetter.cpp +++ b/src/core/function/gpg/GpgKeyGetter.cpp @@ -34,6 +34,7 @@ #include "core/GpgModel.h" #include "core/function/gpg/GpgContext.h" +#include "core/function/gpg/GpgKeyGroupGetter.h" #include "core/utils/GpgUtils.h" namespace GpgFrontend { @@ -70,7 +71,13 @@ class GpgKeyGetter::Impl : public SingletonFunctionObject { gpgme_get_key(ctx_.DefaultContext(), fpr.toUtf8(), &p_key, 0); if (p_key == nullptr) LOG_W() << "GpgKeyGetter GetKey _p_key Null, fpr: " << fpr; - return GpgKey(std::move(p_key)); + return GpgKey(p_key); + } + + auto GetPubkeyPtr(const QString& fpr, bool use_cache) -> GpgKeyPtr { + auto key = GetPubkey(fpr, use_cache); + if (!key.IsGood()) return nullptr; + return QSharedPointer::create(key); } auto FetchKey() -> GpgKeyList { @@ -89,19 +96,20 @@ class GpgKeyGetter::Impl : public SingletonFunctionObject { return keys_list; } - auto FetchGpgKeyList() -> GpgKeyList { + auto FetchGpgKeyList() -> GpgAbstractKeyPtrList { if (keys_search_cache_.empty()) { FlushKeyCache(); } - auto keys_list = GpgKeyList{}; + auto keys_list = GpgAbstractKeyPtrList{}; { // get the lock std::lock_guard lock(keys_cache_mutex_); for (const auto& key : keys_cache_) { - keys_list.push_back(key); + keys_list.push_back(QSharedPointer::create(key)); } } + return keys_list; } @@ -163,9 +171,21 @@ class GpgKeyGetter::Impl : public SingletonFunctionObject { return keys_copy; } - auto GetGpgKeyTableModel() -> QSharedPointer { - return SecureCreateQSharedObject( - SingletonFunctionObject::GetChannel(), FetchGpgKeyList(), nullptr); + auto Fetch() -> QContainer> { + auto keys = FetchKey(); + + auto ret = QContainer>(); + for (const auto& key : keys) { + ret.append(QSharedPointer::create(key)); + } + return ret; + } + + auto GetKeyPtr(const QString& key_id, + bool use_cache) -> QSharedPointer { + auto key = GetKey(key_id, use_cache); + if (!key.IsGood()) return nullptr; + return QSharedPointer::create(key); } private: @@ -229,10 +249,20 @@ auto GpgKeyGetter::GetKey(const QString& key_id, bool use_cache) -> GpgKey { return p_->GetKey(key_id, use_cache); } +auto GpgKeyGetter::GetKeyPtr(const QString& key_id, + bool use_cache) -> QSharedPointer { + return p_->GetKeyPtr(key_id, use_cache); +} + auto GpgKeyGetter::GetPubkey(const QString& key_id, bool use_cache) -> GpgKey { return p_->GetPubkey(key_id, use_cache); } +auto GpgKeyGetter::GetPubkeyPtr(const QString& key_id, + bool use_cache) -> GpgKeyPtr { + return p_->GetPubkeyPtr(key_id, use_cache); +} + auto GpgKeyGetter::FlushKeyCache() -> bool { return p_->FlushKeyCache(); } auto GpgKeyGetter::GetKeys(const KeyIdArgsList& ids) -> GpgKeyList { @@ -245,8 +275,7 @@ auto GpgKeyGetter::GetKeysCopy(const GpgKeyList& keys) -> GpgKeyList { auto GpgKeyGetter::FetchKey() -> GpgKeyList { return p_->FetchKey(); } -auto GpgKeyGetter::GetGpgKeyTableModel() -> QSharedPointer { - return p_->GetGpgKeyTableModel(); +auto GpgKeyGetter::Fetch() -> QContainer> { + return p_->Fetch(); } - } // namespace GpgFrontend diff --git a/src/core/function/gpg/GpgKeyGetter.h b/src/core/function/gpg/GpgKeyGetter.h index 2ed34531..b266bf17 100644 --- a/src/core/function/gpg/GpgKeyGetter.h +++ b/src/core/function/gpg/GpgKeyGetter.h @@ -63,12 +63,14 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter auto GetKey(const QString& key_id, bool use_cache = true) -> GpgKey; /** - * @brief Get the Keys object + * @brief Get the Key Ptr object * - * @param ids - * @return KeyListPtr + * @param key_id + * @param use_cache + * @return QSharedPointer */ - auto GetKeys(const KeyIdArgsList& key_ids) -> GpgKeyList; + auto GetKeyPtr(const QString& key_id, + bool use_cache = true) -> QSharedPointer; /** * @brief Get the Pubkey object @@ -78,6 +80,15 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter */ auto GetPubkey(const QString& key_id, bool use_cache = true) -> GpgKey; + /** + * @brief Get the Pubkey Ptr object + * + * @param key_id + * @param use_cache + * @return GpgKeyPtr + */ + auto GetPubkeyPtr(const QString& key_id, bool use_cache = true) -> GpgKeyPtr; + /** * @brief Get all the keys by receiving a linked list * @@ -85,6 +96,13 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter */ auto FetchKey() -> GpgKeyList; + /** + * @brief + * + * @return QContainer> + */ + auto Fetch() -> QContainer>; + /** * @brief flush the keys in the cache * @@ -92,19 +110,20 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyGetter auto FlushKeyCache() -> bool; /** - * @brief Get the Keys Copy object + * @brief Get the Keys object * - * @param keys + * @param ids * @return KeyListPtr */ - auto GetKeysCopy(const GpgKeyList& keys) -> GpgKeyList; + auto GetKeys(const KeyIdArgsList& key_ids) -> GpgKeyList; /** - * @brief + * @brief Get the Keys Copy object * - * @return GpgKeyTableModel + * @param keys + * @return KeyListPtr */ - auto GetGpgKeyTableModel() -> QSharedPointer; + auto GetKeysCopy(const GpgKeyList& keys) -> GpgKeyList; private: class Impl; diff --git a/src/core/function/gpg/GpgKeyGroupGetter.cpp b/src/core/function/gpg/GpgKeyGroupGetter.cpp new file mode 100644 index 00000000..47878414 --- /dev/null +++ b/src/core/function/gpg/GpgKeyGroupGetter.cpp @@ -0,0 +1,311 @@ +/** + * Copyright (C) 2021-2024 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend 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 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend 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 GpgFrontend. If not, see . + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "GpgKeyGroupGetter.h" + +#include "core/function/CacheManager.h" +#include "core/function/gpg/GpgAbstractKeyGetter.h" +#include "core/struct/cache_object/KeyGroupsCO.h" +#include "utils/GpgUtils.h" + +namespace GpgFrontend { + +GpgKeyGroupGetter::GpgKeyGroupGetter(int channel) + : SingletonFunctionObject(channel) { + fetch_key_groups(); +} + +auto GpgKeyGroupGetter::Fetch() -> QContainer> { + QContainer> ret; + for (const auto& node : key_groups_forest_) { + ret.push_back(node->key_group); + } + return ret; +} + +void GpgKeyGroupGetter::Remove(const QString& id) { + if (id.isEmpty() || !key_groups_forest_.contains(id)) return; + + auto target_node = key_groups_forest_.value(id); + + for (const auto& node : key_groups_forest_) { + if (target_node == node) continue; + node->RemoveChildren(target_node.get()); + } + + key_groups_forest_.remove(id); + FlushCache(); +} + +void GpgKeyGroupGetter::fetch_key_groups() { + key_groups_forest_.clear(); + auto key = QString("kgs:%1").arg(ctx_.KeyDBName()); + auto json = cm_.LoadDurableCache(key); + + auto key_groups = KeyGroupsCO(json.object()); + if (key_groups.key_db_name != ctx_.KeyDBName()) return; + + for (const auto& key_group : key_groups.key_groups) { + if (key_group.id.isEmpty()) continue; + + LOG_D() << "load raw key group:" << key_group.id + << "key ids: " << key_group.key_ids; + + key_groups_forest_.insert( + key_group.id, + QSharedPointer::create(GpgKeyGroup{key_group})); + } + + build_gpg_key_group_tree(); + check_all_key_groups(); +} + +void GpgKeyGroupGetter::persist_key_groups() { + auto key = QString("kgs:%1").arg(ctx_.KeyDBName()); + + KeyGroupsCO key_groups; + key_groups.key_db_name = ctx_.KeyDBName(); + + for (const auto& node : key_groups_forest_) { + if (node->key_group == nullptr) continue; + LOG_D() << "persist key group: " << node->key_group->ID() + << "key ids:" << node->key_group->KeyIds(); + key_groups.key_groups.push_back(node->key_group->ToCacheObject()); + } + + cm_.SaveDurableCache(key, QJsonDocument{key_groups.ToJson()}, true); +} + +auto GpgKeyGroupGetter::KeyGroup(const QString& id) + -> QSharedPointer { + if (!key_groups_forest_.contains(id)) return nullptr; + return key_groups_forest_.value(id)->key_group; +} + +void GpgKeyGroupGetter::check_key_group( + const QSharedPointer& key_group) { + if (key_group == nullptr || key_group->IsDisabled()) return; + + for (const auto& key_id : key_group->KeyIds()) { + LOG_D() << "check" << key_id << "of" << key_group->UID(); + + if (IsKeyGroupID(key_id) || key_id == key_group->ID()) { + if (!key_groups_forest_.contains(key_id)) { + key_group->SetDisabled(true); + return; + } + + auto s_node = key_groups_forest_.value(key_id, nullptr); + check_key_group(s_node->key_group); + + if (s_node->key_group->IsDisabled()) { + key_group->SetDisabled(true); + return; + } + + } else { + auto key = GpgKeyGetter::GetInstance(GetChannel()).GetKeyPtr(key_id); + if (key == nullptr || !key->IsHasEncrCap()) { + key_group->SetDisabled(true); + return; + } + } + } +} + +void GpgKeyGroupGetter::check_all_key_groups() { + for (const auto& node : key_groups_forest_) { + node->key_group->SetDisabled(false); + } + + for (const auto& node : key_groups_forest_) { + auto key_group = node->key_group; + check_key_group(key_group); + + LOG_D() << "key group" << key_group->ID() << "ids: " << key_group->KeyIds() + << "status: " << key_group->IsDisabled(); + } +} + +auto GpgKeyGroupGetter::FlushCache() -> bool { + check_all_key_groups(); + persist_key_groups(); + return true; +} + +void GpgKeyGroupGetter::build_gpg_key_group_tree() { + for (const auto& node : key_groups_forest_) { + LOG_D() << "load key group: " << node->key_group->ID() + << "ids: " << node->key_group->KeyIds(); + for (const auto& key_id : node->key_group->KeyIds()) { + if (!IsKeyGroupID(key_id) || !key_groups_forest_.contains(key_id)) { + continue; + } + + auto target = key_groups_forest_.value(key_id); + if (!node->AddChildren(target.get())) { + LOG_E() << "found ring in key groups relations, key group:" + << node->key_group->ID() << "child: " << key_id; + continue; + } + } + node->Apply(); + } +} + +void GpgKeyGroupGetter::AddKeyGroup(const GpgKeyGroup& key_group) { + auto node = QSharedPointer::create(key_group); + + key_groups_forest_.insert(node->key_group->ID(), node); + LOG_D() << "add new key group" << key_group.ID() + << "key ids:" << key_group.KeyIds(); + + for (const auto& key_id : node->key_group->KeyIds()) { + if (!IsKeyGroupID(key_id) || !key_groups_forest_.contains(key_id)) continue; + + auto target = key_groups_forest_.value(key_id); + node->AddChildren(target.get()); + } + node->Apply(); + FlushCache(); +} + +auto GpgKeyGroupGetter::AddKey2KeyGroup(const QString& id, + const GpgAbstractKeyPtr& key) -> bool { + if (!key_groups_forest_.contains(id)) return false; + auto key_group = key_groups_forest_.value(id); + + if (key->KeyType() != GpgAbstractKeyType::kGPG_KEYGROUP) { + auto ret = key_group->AddNonKeyGroupKey(key); + FlushCache(); + return ret; + } + + if (!key_groups_forest_.contains(key->ID())) { + LOG_E() << "try adding invalid key group id:" << key->ID(); + return false; + } + + auto s_key_group = key_groups_forest_.value(key->ID()); + auto ret = key_group->AddChildren(s_key_group.get()); + FlushCache(); + return ret; +} + +auto GpgKeyGroupGetter::RemoveKeyFromKeyGroup(const QString& id, + const QString& key_id) -> bool { + if (!key_groups_forest_.contains(id)) return false; + auto key_group = key_groups_forest_.value(id); + + if (!IsKeyGroupID(key_id)) { + LOG_D() << "removing non key group id" << key_id << "form key group" << id; + key_group->RemoveNonKeyGroupKey(key_id); + FlushCache(); + return true; + } + + if (!key_groups_forest_.contains(key_id)) { + LOG_E() << "try remove invalid key group id:" << key_id; + return false; + } + + auto s_key_group = key_groups_forest_.value(key_id); + auto ret = key_group->RemoveChildren(s_key_group.get()); + FlushCache(); + return ret; +} + +GpgKeyGroupTreeNode::GpgKeyGroupTreeNode(GpgKeyGroup kg) + : key_group(QSharedPointer::create(kg)) { + for (const auto& key_id : key_group->KeyIds()) { + if (!IsKeyGroupID(key_id)) { + non_key_group_ids.push_back(key_id); + } + } +} + +void GpgKeyGroupTreeNode::Apply() { + QStringList key_ids; + for (const auto& child : children) { + key_ids.push_back(child->key_group->ID()); + } + + for (const auto& key_id : non_key_group_ids) { + key_ids.push_back(key_id); + } + + key_group->SetKeyIds(key_ids); +} + +auto GpgKeyGroupTreeNode::AddNonKeyGroupKey(const GpgAbstractKeyPtr& key) + -> bool { + if (key->KeyType() == GpgAbstractKeyType::kGPG_KEYGROUP || + non_key_group_ids.contains(key->ID())) { + return false; + } + non_key_group_ids.push_back(key->ID()); + non_key_group_ids.removeDuplicates(); + Apply(); + return true; +} + +auto GpgKeyGroupTreeNode::HasAncestor(GpgKeyGroupTreeNode* target) -> bool { + for (const auto& parent : parents) { + if (parent == target || parent->HasAncestor(target)) { + return true; + } + } + return false; +} + +auto GpgKeyGroupTreeNode::AddChildren(GpgKeyGroupTreeNode* target) -> bool { + if (target == this || children.contains(target) || HasAncestor(target)) { + return false; + } + + children.push_back(target); + target->parents.push_back(this); + Apply(); + return true; +} + +auto GpgKeyGroupTreeNode::RemoveChildren(GpgKeyGroupTreeNode* target) -> bool { + if (!children.contains(target)) return false; + children.removeAll(target); + target->parents.removeAll(this); + Apply(); + return true; +} + +auto GpgKeyGroupTreeNode::RemoveNonKeyGroupKey(const QString& key) -> bool { + if (!non_key_group_ids.contains(key)) return false; + non_key_group_ids.removeAll(key); + Apply(); + return true; +} +} // namespace GpgFrontend \ No newline at end of file diff --git a/src/core/function/gpg/GpgKeyGroupGetter.h b/src/core/function/gpg/GpgKeyGroupGetter.h new file mode 100644 index 00000000..9eabccde --- /dev/null +++ b/src/core/function/gpg/GpgKeyGroupGetter.h @@ -0,0 +1,215 @@ +/** + * Copyright (C) 2021-2024 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend 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 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend 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 GpgFrontend. If not, see . + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#pragma once + +#include "core/function/CacheManager.h" +#include "core/function/basic/GpgFunctionObject.h" +#include "core/function/gpg/GpgContext.h" +#include "core/model/GpgKeyGroup.h" + +namespace GpgFrontend { + +struct GpgKeyGroupTreeNode { + QContainer parents; + QContainer children; + QSharedPointer key_group; + + // over take + QStringList non_key_group_ids; + + /** + * @brief Construct a new Gpg Key Group Tree Node object + * + */ + GpgKeyGroupTreeNode() = default; + + /** + * @brief Construct a new Gpg Key Group Tree Node object + * + * @param kg + */ + explicit GpgKeyGroupTreeNode(GpgKeyGroup kg); + + /** + * @brief + * + */ + void Apply(); + + /** + * @brief + * + * @param key + * @return true + * @return false + */ + auto AddNonKeyGroupKey(const GpgAbstractKeyPtr& key) -> bool; + + /** + * @brief + * + * @param target + * @return true + * @return false + */ + auto HasAncestor(GpgKeyGroupTreeNode* target) -> bool; + + /** + * @brief + * + * @param target + * @return true + * @return false + */ + auto AddChildren(GpgKeyGroupTreeNode* target) -> bool; + + /** + * @brief + * + * @param target + * @return true + * @return false + */ + auto RemoveChildren(GpgKeyGroupTreeNode* target) -> bool; + + /** + * @brief + * + * @param key + * @return true + * @return false + */ + auto RemoveNonKeyGroupKey(const QString& key) -> bool; +}; + +class GPGFRONTEND_CORE_EXPORT GpgKeyGroupGetter + : public SingletonFunctionObject { + public: + /** + * @brief GpgKeyGroupGetter constructor + * + * @param channel channel + */ + explicit GpgKeyGroupGetter( + int channel = SingletonFunctionObject::GetDefaultChannel()); + + /** + * @brief + * + * @return QContainer + */ + auto Fetch() -> QContainer>; + + /** + * @brief + * + * @return QContainer + */ + auto FlushCache() -> bool; + + /** + * @brief + * + */ + void AddKeyGroup(const GpgKeyGroup&); + + /** + * @brief + * + * @param id + * @param key + * @return true + * @return false + */ + auto AddKey2KeyGroup(const QString& id, const GpgAbstractKeyPtr& key) -> bool; + + /** + * @brief + * + * @param id + * @param key + * @return true + * @return false + */ + auto RemoveKeyFromKeyGroup(const QString& id, const QString& key_id) -> bool; + + /** + * @brief + * + * @param id + */ + void Remove(const QString& id); + + /** + * @brief + * + * @param id + */ + auto KeyGroup(const QString& id) -> QSharedPointer; + + private: + GpgContext& ctx_ = + GpgContext::GetInstance(SingletonFunctionObject::GetChannel()); + CacheManager& cm_ = + CacheManager::GetInstance(SingletonFunctionObject::GetChannel()); + + QMap> key_groups_forest_; + + /** + * @brief + * + */ + void fetch_key_groups(); + + /** + * @brief + * + */ + void persist_key_groups(); + + /** + * @brief + * + */ + void check_all_key_groups(); + + /** + * @brief + * + */ + void check_key_group(const QSharedPointer&); + + /** + * @brief + * + */ + void build_gpg_key_group_tree(); +}; + +} // namespace GpgFrontend diff --git a/src/core/function/gpg/GpgKeyImportExporter.cpp b/src/core/function/gpg/GpgKeyImportExporter.cpp index 60c06995..08e67748 100644 --- a/src/core/function/gpg/GpgKeyImportExporter.cpp +++ b/src/core/function/gpg/GpgKeyImportExporter.cpp @@ -72,21 +72,18 @@ auto GpgKeyImportExporter::ImportKey(const GFBuffer& in_buffer) * @param outBuffer output byte array * @return if success */ -auto GpgKeyImportExporter::ExportKey(const GpgKey& key, bool secret, bool ascii, - bool shortest, bool ssh_mode) const - -> std::tuple { - if (!key.IsGood()) return {GPG_ERR_CANCELED, {}}; +auto GpgKeyImportExporter::ExportKey( + const GpgAbstractKeyPtr& key, bool secret, bool ascii, bool shortest, + bool ssh_mode) const -> std::tuple { + if (key == nullptr) return {GPG_ERR_CANCELED, {}}; int mode = 0; if (secret) mode |= GPGME_EXPORT_MODE_SECRET; if (shortest) mode |= GPGME_EXPORT_MODE_MINIMAL; if (ssh_mode) mode |= GPGME_EXPORT_MODE_SSH; - QContainer keys_array; - - // Last entry data_in array has to be nullptr - keys_array.push_back(static_cast(key)); - keys_array.push_back(nullptr); + QContainer keys_array = + Convert2RawGpgMEKeyList(GetChannel(), {key}); GpgData data_out; auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext(); @@ -102,8 +99,9 @@ auto GpgKeyImportExporter::ExportKey(const GpgKey& key, bool secret, bool ascii, * @param outBuffer output byte array * @return if success */ -void GpgKeyImportExporter::ExportKeys(const KeyArgsList& keys, bool secret, - bool ascii, bool shortest, bool ssh_mode, +void GpgKeyImportExporter::ExportKeys(const GpgAbstractKeyPtrList& keys, + bool secret, bool ascii, bool shortest, + bool ssh_mode, const GpgOperationCallback& cb) const { RunGpgOperaAsync( [=](const DataObjectPtr& data_object) -> GpgError { @@ -114,7 +112,7 @@ void GpgKeyImportExporter::ExportKeys(const KeyArgsList& keys, bool secret, if (shortest) mode |= GPGME_EXPORT_MODE_MINIMAL; if (ssh_mode) mode |= GPGME_EXPORT_MODE_SSH; - QContainer keys_array(keys.begin(), keys.end()); + auto keys_array = Convert2RawGpgMEKeyList(GetChannel(), keys); // Last entry data_in array has to be nullptr keys_array.push_back(nullptr); @@ -136,15 +134,15 @@ void GpgKeyImportExporter::ExportKeys(const KeyArgsList& keys, bool secret, * @param outBuffer output byte array * @return if success */ -void GpgKeyImportExporter::ExportAllKeys(const KeyArgsList& keys, bool secret, - bool ascii, +void GpgKeyImportExporter::ExportAllKeys(const GpgAbstractKeyPtrList& keys, + bool secret, bool ascii, const GpgOperationCallback& cb) const { RunGpgOperaAsync( [=](const DataObjectPtr& data_object) -> GpgError { if (keys.empty()) return GPG_ERR_CANCELED; int mode = 0; - QContainer keys_array(keys.begin(), keys.end()); + auto keys_array = Convert2RawGpgMEKeyList(GetChannel(), keys); // Last entry data_in array has to be nullptr keys_array.push_back(nullptr); diff --git a/src/core/function/gpg/GpgKeyImportExporter.h b/src/core/function/gpg/GpgKeyImportExporter.h index cc7b3f6f..4f938cb7 100644 --- a/src/core/function/gpg/GpgKeyImportExporter.h +++ b/src/core/function/gpg/GpgKeyImportExporter.h @@ -68,9 +68,9 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyImportExporter * @param ascii * @return std::tuple */ - [[nodiscard]] auto ExportKey(const GpgKey& key, bool secret, bool ascii, - bool shortest, bool ssh_mode = false) const - -> std::tuple; + [[nodiscard]] auto ExportKey( + const GpgAbstractKeyPtr& key, bool secret, bool ascii, bool shortest, + bool ssh_mode = false) const -> std::tuple; /** * @brief @@ -91,7 +91,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyImportExporter * @return true * @return false */ - void ExportKeys(const KeyArgsList& keys, bool secret, bool ascii, + void ExportKeys(const GpgAbstractKeyPtrList& keys, bool secret, bool ascii, bool shortest, bool ssh_mode, const GpgOperationCallback& cb) const; @@ -103,7 +103,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyImportExporter * @param ascii * @param cb */ - void ExportAllKeys(const KeyArgsList& keys, bool secret, bool ascii, + void ExportAllKeys(const GpgAbstractKeyPtrList& keys, bool secret, bool ascii, const GpgOperationCallback& cb) const; private: diff --git a/src/core/function/gpg/GpgKeyManager.cpp b/src/core/function/gpg/GpgKeyManager.cpp index bd514cf3..a2c53975 100644 --- a/src/core/function/gpg/GpgKeyManager.cpp +++ b/src/core/function/gpg/GpgKeyManager.cpp @@ -39,7 +39,8 @@ namespace GpgFrontend { GpgKeyManager::GpgKeyManager(int channel) : SingletonFunctionObject(channel) {} -auto GpgKeyManager::SignKey(const GpgKey& target, KeyArgsList& keys, +auto GpgKeyManager::SignKey(const GpgKeyPtr& key, + const GpgAbstractKeyPtrList& keys, const QString& uid, const std::unique_ptr& expires) -> bool { GpgBasicOperator::GetInstance(GetChannel()).SetSigners(keys, true); @@ -54,13 +55,13 @@ auto GpgKeyManager::SignKey(const GpgKey& target, KeyArgsList& keys, } auto err = CheckGpgError( - gpgme_op_keysign(ctx_.DefaultContext(), static_cast(target), + gpgme_op_keysign(ctx_.DefaultContext(), static_cast(*key), uid.toUtf8(), expires_time_t, flags)); return CheckGpgError(err) == GPG_ERR_NO_ERROR; } -auto GpgKeyManager::RevSign(const GpgKey& key, +auto GpgKeyManager::RevSign(const GpgKeyPtr& key, const SignIdArgsList& signature_id) -> bool { auto& key_getter = GpgKeyGetter::GetInstance(GetChannel()); @@ -69,14 +70,14 @@ auto GpgKeyManager::RevSign(const GpgKey& key, assert(signing_key.IsGood()); auto err = CheckGpgError( - gpgme_op_revsig(ctx_.DefaultContext(), gpgme_key_t(key), + gpgme_op_revsig(ctx_.DefaultContext(), gpgme_key_t(*key), gpgme_key_t(signing_key), sign_id.second.toUtf8(), 0)); if (CheckGpgError(err) != GPG_ERR_NO_ERROR) return false; } return true; } -auto GpgKeyManager::SetExpire(const GpgKey& key, +auto GpgKeyManager::SetExpire(const GpgKeyPtr& key, std::unique_ptr& subkey, std::unique_ptr& expires) -> bool { unsigned long expires_time = 0; @@ -88,13 +89,13 @@ auto GpgKeyManager::SetExpire(const GpgKey& key, if (subkey != nullptr) sub_fprs = subkey->Fingerprint().toUtf8(); auto err = CheckGpgError(gpgme_op_setexpire(ctx_.DefaultContext(), - static_cast(key), + static_cast(*key), expires_time, sub_fprs, 0)); return CheckGpgError(err) == GPG_ERR_NO_ERROR; } -auto GpgKeyManager::SetOwnerTrustLevel(const GpgKey& key, +auto GpgKeyManager::SetOwnerTrustLevel(const GpgKeyPtr& key, int trust_level) -> bool { if (trust_level < 1 || trust_level > 5) { FLOG_W("illegal owner trust level: %d", trust_level); @@ -172,9 +173,10 @@ auto GpgKeyManager::SetOwnerTrustLevel(const GpgKey& key, .DoInteract(key, next_state_handler, action_handler); } -auto GpgKeyManager::DeleteSubkey(const GpgKey& key, int subkey_index) -> bool { +auto GpgKeyManager::DeleteSubkey(const GpgKeyPtr& key, + int subkey_index) -> bool { if (subkey_index < 0 || - subkey_index >= static_cast(key.SubKeys().size())) { + subkey_index >= static_cast(key->SubKeys().size())) { LOG_W() << "illegal subkey index: " << subkey_index; return false; } @@ -246,7 +248,7 @@ auto GpgKeyManager::DeleteSubkey(const GpgKey& key, int subkey_index) -> bool { return QString(""); }; - auto key_fpr = key.Fingerprint(); + auto key_fpr = key->Fingerprint(); AutomatonHandelStruct handel_struct(key_fpr); handel_struct.SetHandler(next_state_handler, action_handler); @@ -256,11 +258,11 @@ auto GpgKeyManager::DeleteSubkey(const GpgKey& key, int subkey_index) -> bool { .DoInteract(key, next_state_handler, action_handler); } -auto GpgKeyManager::RevokeSubkey(const GpgKey& key, int subkey_index, +auto GpgKeyManager::RevokeSubkey(const GpgKeyPtr& key, int subkey_index, int reason_code, const QString& reason_text) -> bool { if (subkey_index < 0 || - subkey_index >= static_cast(key.SubKeys().size())) { + subkey_index >= static_cast(key->SubKeys().size())) { LOG_W() << "illegal subkey index: " << subkey_index; return false; } @@ -369,7 +371,7 @@ auto GpgKeyManager::RevokeSubkey(const GpgKey& key, int subkey_index, return QString(""); }; - auto key_fpr = key.Fingerprint(); + auto key_fpr = key->Fingerprint(); AutomatonHandelStruct handel_struct(key_fpr); handel_struct.SetHandler(next_state_handler, action_handler); diff --git a/src/core/function/gpg/GpgKeyManager.h b/src/core/function/gpg/GpgKeyManager.h index 817179e1..ccf69b53 100644 --- a/src/core/function/gpg/GpgKeyManager.h +++ b/src/core/function/gpg/GpgKeyManager.h @@ -51,12 +51,13 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyManager /** * @brief Sign a key pair(actually a certain uid) - * @param target target key pair + * @param key target key pair * @param uid target * @param expires expire date and time of the signature * @return if successful */ - auto SignKey(const GpgKey& target, KeyArgsList& keys, const QString& uid, + auto SignKey(const GpgKeyPtr& key, const GpgAbstractKeyPtrList& keys, + const QString& uid, const std::unique_ptr& expires) -> bool; /** @@ -67,8 +68,8 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyManager * @return true * @return false */ - auto RevSign(const GpgFrontend::GpgKey& key, - const GpgFrontend::SignIdArgsList& signature_id) -> bool; + auto RevSign(const GpgKeyPtr& key, + const SignIdArgsList& signature_id) -> bool; /** * @brief Set the Expire object @@ -79,7 +80,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyManager * @return true * @return false */ - auto SetExpire(const GpgKey& key, std::unique_ptr& subkey, + auto SetExpire(const GpgKeyPtr& key, std::unique_ptr& subkey, std::unique_ptr& expires) -> bool; /** @@ -87,7 +88,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyManager * * @return */ - auto SetOwnerTrustLevel(const GpgKey& key, int trust_level) -> bool; + auto SetOwnerTrustLevel(const GpgKeyPtr& key, int trust_level) -> bool; /** * @brief @@ -97,7 +98,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyManager * @return true * @return false */ - auto DeleteSubkey(const GpgKey& key, int subkey_index) -> bool; + auto DeleteSubkey(const GpgKeyPtr& key, int subkey_index) -> bool; /** * @brief @@ -107,7 +108,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyManager * @return true * @return false */ - auto RevokeSubkey(const GpgKey& key, int subkey_index, int reason_code, + auto RevokeSubkey(const GpgKeyPtr& key, int subkey_index, int reason_code, const QString& reason_text) -> bool; private: diff --git a/src/core/function/gpg/GpgKeyOpera.cpp b/src/core/function/gpg/GpgKeyOpera.cpp index 3d9b8eda..3e4fe6d4 100644 --- a/src/core/function/gpg/GpgKeyOpera.cpp +++ b/src/core/function/gpg/GpgKeyOpera.cpp @@ -28,9 +28,8 @@ #include "GpgKeyOpera.h" -#include "core/GpgModel.h" #include "core/function/gpg/GpgCommandExecutor.h" -#include "core/function/gpg/GpgKeyGetter.h" +#include "core/function/gpg/GpgKeyGroupGetter.h" #include "core/model/DataObject.h" #include "core/model/GpgGenerateKeyResult.h" #include "core/model/GpgKeyGenerateInfo.h" @@ -49,17 +48,21 @@ GpgKeyOpera::GpgKeyOpera(int channel) * Delete keys * @param uidList key ids */ -void GpgKeyOpera::DeleteKeys(KeyIdArgsList key_ids) { +void GpgKeyOpera::DeleteKeys(const GpgAbstractKeyPtrList& keys) { GpgError err; - for (const auto& tmp : key_ids) { - auto key = GpgKeyGetter::GetInstance(GetChannel()).GetKey(tmp); - if (key.IsGood()) { + for (const auto& key : keys) { + if (key->KeyType() == GpgAbstractKeyType::kGPG_KEY && key->IsGood()) { + auto k = qSharedPointerDynamicCast(key); err = CheckGpgError(gpgme_op_delete_ext( - ctx_.DefaultContext(), static_cast(key), + ctx_.DefaultContext(), static_cast(*k), GPGME_DELETE_ALLOW_SECRET | GPGME_DELETE_FORCE)); assert(gpg_err_code(err) == GPG_ERR_NO_ERROR); } else { - LOG_W() << "GpgKeyOpera DeleteKeys get key failed: " << tmp; + LOG_W() << "GpgKeyOpera DeleteKeys get key failed: " << key->ID(); + } + + if (key->KeyType() == GpgAbstractKeyType::kGPG_KEYGROUP) { + GpgKeyGroupGetter::GetInstance(GetChannel()).Remove(key->ID()); } } } @@ -72,7 +75,7 @@ void GpgKeyOpera::DeleteKeys(KeyIdArgsList key_ids) { * @param expires date and time * @return if successful */ -auto GpgKeyOpera::SetExpire(const GpgKey& key, const SubkeyId& subkey_fpr, +auto GpgKeyOpera::SetExpire(const GpgKeyPtr& key, const SubkeyId& subkey_fpr, std::unique_ptr& expires) -> GpgError { unsigned long expires_time = 0; @@ -81,15 +84,15 @@ auto GpgKeyOpera::SetExpire(const GpgKey& key, const SubkeyId& subkey_fpr, } GpgError err; - if (key.Fingerprint() == subkey_fpr || subkey_fpr.isEmpty()) { - err = - gpgme_op_setexpire(ctx_.DefaultContext(), static_cast(key), - expires_time, nullptr, 0); + if (key->Fingerprint() == subkey_fpr || subkey_fpr.isEmpty()) { + err = gpgme_op_setexpire(ctx_.DefaultContext(), + static_cast(*key), expires_time, + nullptr, 0); assert(gpg_err_code(err) == GPG_ERR_NO_ERROR); } else { - err = - gpgme_op_setexpire(ctx_.DefaultContext(), static_cast(key), - expires_time, subkey_fpr.toUtf8(), 0); + err = gpgme_op_setexpire(ctx_.DefaultContext(), + static_cast(*key), expires_time, + subkey_fpr.toUtf8(), 0); assert(gpg_err_code(err) == GPG_ERR_NO_ERROR); } @@ -102,7 +105,7 @@ auto GpgKeyOpera::SetExpire(const GpgKey& key, const SubkeyId& subkey_fpr, * @param outputFileName out file name(path) * @return the process doing this job */ -void GpgKeyOpera::GenerateRevokeCert(const GpgKey& key, +void GpgKeyOpera::GenerateRevokeCert(const GpgKeyPtr& key, const QString& output_path, int revocation_reason_code, const QString& revocation_reason_text) { @@ -119,7 +122,7 @@ void GpgKeyOpera::GenerateRevokeCert(const GpgKey& key, GpgCommandExecutor::ExecuteSync( {app_path, QStringList{"--command-fd", "0", "--status-fd", "1", "--no-tty", "-o", - output_path, "--gen-revoke", key.Fingerprint()}, + output_path, "--gen-revoke", key->Fingerprint()}, [=](int exit_code, const QString& p_out, const QString& p_err) { if (exit_code != 0) { LOG_W() << "gnupg gen revoke execute error, process stderr: " @@ -226,7 +229,7 @@ auto GpgKeyOpera::GenerateKeySync(const QSharedPointer& params) "gpgme_op_createkey", "2.1.0"); } -auto GenerateSubKeyImpl(GpgContext& ctx, const GpgKey& key, +auto GenerateSubKeyImpl(GpgContext& ctx, const GpgKeyPtr& key, const QSharedPointer& params, const DataObjectPtr& data_object) -> GpgError { if (params == nullptr || params->GetAlgo() == KeyGenerateInfo::kNoneAlgo || @@ -246,11 +249,12 @@ auto GenerateSubKeyImpl(GpgContext& ctx, const GpgKey& key, if (params->IsNonExpired()) flags |= GPGME_CREATE_NOEXPIRE; if (params->IsNoPassPhrase()) flags |= GPGME_CREATE_NOPASSWD; - LOG_D() << "subkey generation args: " << key.ID() << algo << expires << flags; + LOG_D() << "subkey generation args: " << key->ID() << algo << expires + << flags; - auto err = - gpgme_op_createsubkey(ctx.DefaultContext(), static_cast(key), - algo.toLatin1(), 0, expires, flags); + auto err = gpgme_op_createsubkey(ctx.DefaultContext(), + static_cast(*key), + algo.toLatin1(), 0, expires, flags); if (CheckGpgError(err) != GPG_ERR_NO_ERROR) { data_object->Swap({GpgGenerateKeyResult{}}); return err; @@ -261,7 +265,7 @@ auto GenerateSubKeyImpl(GpgContext& ctx, const GpgKey& key, return CheckGpgError(err); } -void GpgKeyOpera::GenerateSubkey(const GpgKey& key, +void GpgKeyOpera::GenerateSubkey(const GpgKeyPtr& key, const QSharedPointer& params, const GpgOperationCallback& callback) { RunGpgOperaAsync( @@ -272,7 +276,7 @@ void GpgKeyOpera::GenerateSubkey(const GpgKey& key, } auto GpgKeyOpera::GenerateSubkeySync( - const GpgKey& key, const QSharedPointer& params) + const GpgKeyPtr& key, const QSharedPointer& params) -> std::tuple { return RunGpgOperaSync( [=](const DataObjectPtr& data_object) -> GpgError { @@ -291,8 +295,8 @@ auto GenerateKeyWithSubkeyImpl(GpgContext& ctx, GpgKeyGetter& key_getter, if (!data_object->Check()) return GPG_ERR_CANCELED; auto result = ExtractParams(data_object, 0); - auto key = key_getter.GetKey(result.GetFingerprint()); - if (!key.IsGood()) { + auto key = key_getter.GetKeyPtr(result.GetFingerprint()); + if (key == nullptr) { LOG_W() << "cannot get key which has been generated, fpr: " << result.GetFingerprint(); return GPG_ERR_CANCELED; @@ -332,18 +336,18 @@ auto GpgKeyOpera::GenerateKeyWithSubkeySync( "gpgme_op_createkey&gpgme_op_createsubkey", "2.1.0"); } -void GpgKeyOpera::ModifyPassword(const GpgKey& key, +void GpgKeyOpera::ModifyPassword(const GpgKeyPtr& key, const GpgOperationCallback& callback) { RunGpgOperaAsync( [&key, &ctx = ctx_](const DataObjectPtr&) -> GpgError { return gpgme_op_passwd(ctx.DefaultContext(), - static_cast(key), 0); + static_cast(*key), 0); }, callback, "gpgme_op_passwd", "2.0.15"); } auto GpgKeyOpera::ModifyTOFUPolicy( - const GpgKey& key, gpgme_tofu_policy_t tofu_policy) -> GpgError { + const GpgKeyPtr& key, gpgme_tofu_policy_t tofu_policy) -> GpgError { const auto gnupg_version = Module::RetrieveRTValueTypedOrDefault<>( "core", "gpgme.ctx.gnupg_version", QString{"2.0.0"}); LOG_D() << "got gnupg version from rt: " << gnupg_version; @@ -354,26 +358,22 @@ auto GpgKeyOpera::ModifyTOFUPolicy( } auto err = gpgme_op_tofu_policy(ctx_.DefaultContext(), - static_cast(key), tofu_policy); + static_cast(*key), tofu_policy); return CheckGpgError(err); } -void GpgKeyOpera::DeleteKey(const KeyId& key_id) { - auto keys = KeyIdArgsList{}; - keys.push_back(key_id); - DeleteKeys(keys); -} +void GpgKeyOpera::DeleteKey(const GpgAbstractKeyPtr& key) { DeleteKeys({key}); } -auto AddADSKImpl(GpgContext& ctx, const GpgKey& key, const GpgSubKey& adsk, +auto AddADSKImpl(GpgContext& ctx, const GpgKeyPtr& key, const GpgSubKey& adsk, const DataObjectPtr& data_object) -> GpgError { auto algo = adsk.Fingerprint(); unsigned int flags = GPGME_CREATE_ADSK; - LOG_D() << "add adsk args: " << key.ID() << algo; + LOG_D() << "add adsk args: " << key->ID() << algo; - auto err = - gpgme_op_createsubkey(ctx.DefaultContext(), static_cast(key), - algo.toLatin1(), 0, 0, flags); + auto err = gpgme_op_createsubkey(ctx.DefaultContext(), + static_cast(*key), + algo.toLatin1(), 0, 0, flags); if (CheckGpgError(err) != GPG_ERR_NO_ERROR) { data_object->Swap({GpgGenerateKeyResult{}}); return err; @@ -384,7 +384,7 @@ auto AddADSKImpl(GpgContext& ctx, const GpgKey& key, const GpgSubKey& adsk, return CheckGpgError(err); } -void GpgKeyOpera::AddADSK(const GpgKey& key, const GpgSubKey& adsk, +void GpgKeyOpera::AddADSK(const GpgKeyPtr& key, const GpgSubKey& adsk, const GpgOperationCallback& callback) { RunGpgOperaAsync( [=](const DataObjectPtr& data_object) -> GpgError { @@ -393,7 +393,7 @@ void GpgKeyOpera::AddADSK(const GpgKey& key, const GpgSubKey& adsk, callback, "gpgme_op_createsubkey", "2.4.1"); } -auto GpgKeyOpera::AddADSKSync(const GpgKey& key, const GpgSubKey& adsk) +auto GpgKeyOpera::AddADSKSync(const GpgKeyPtr& key, const GpgSubKey& adsk) -> std::tuple { return RunGpgOperaSync( [=](const DataObjectPtr& data_object) -> GpgError { diff --git a/src/core/function/gpg/GpgKeyOpera.h b/src/core/function/gpg/GpgKeyOpera.h index 4728992d..0b91f88a 100644 --- a/src/core/function/gpg/GpgKeyOpera.h +++ b/src/core/function/gpg/GpgKeyOpera.h @@ -61,14 +61,14 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera * * @param key_ids */ - void DeleteKeys(KeyIdArgsList key_ids); + void DeleteKeys(const GpgAbstractKeyPtrList& keys); /** * @brief * * @param key_id */ - void DeleteKey(const KeyId& key_id); + void DeleteKey(const GpgAbstractKeyPtr& key_id); /** * @brief Set the Expire object @@ -78,7 +78,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera * @param expires * @return GpgError */ - auto SetExpire(const GpgKey& key, const SubkeyId& subkey_fpr, + auto SetExpire(const GpgKeyPtr& key, const SubkeyId& subkey_fpr, std::unique_ptr& expires) -> GpgError; /** @@ -87,7 +87,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera * @param key * @param output_file_name */ - void GenerateRevokeCert(const GpgKey& key, const QString& output_path, + void GenerateRevokeCert(const GpgKeyPtr& key, const QString& output_path, int revocation_reason_code, const QString& revocation_reason_text); @@ -97,7 +97,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera * @param key * @return GpgFrontend::GpgError */ - void ModifyPassword(const GpgKey& key, const GpgOperationCallback&); + void ModifyPassword(const GpgKeyPtr& key, const GpgOperationCallback&); /** * @brief @@ -106,8 +106,8 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera * @param tofu_policy * @return GpgFrontend::GpgError */ - auto ModifyTOFUPolicy(const GpgKey& key, gpgme_tofu_policy_t tofu_policy) - -> GpgFrontend::GpgError; + auto ModifyTOFUPolicy(const GpgKeyPtr& key, + gpgme_tofu_policy_t tofu_policy) -> GpgError; /** * @brief * @@ -133,7 +133,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera * @param params * @return GpgFrontend::GpgError */ - void GenerateSubkey(const GpgKey& key, + void GenerateSubkey(const GpgKeyPtr& key, const QSharedPointer& params, const GpgOperationCallback&); @@ -143,7 +143,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera * @param key * @param params */ - auto GenerateSubkeySync(const GpgKey& key, + auto GenerateSubkeySync(const GpgKeyPtr& key, const QSharedPointer& params) -> std::tuple; @@ -176,7 +176,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera * @param key * @param adsk */ - void AddADSK(const GpgKey& key, const GpgSubKey& adsk, + void AddADSK(const GpgKeyPtr& key, const GpgSubKey& adsk, const GpgOperationCallback&); /** @@ -186,7 +186,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyOpera * @param adsk * @return GpgError */ - auto AddADSKSync(const GpgKey& key, const GpgSubKey& adsk) + auto AddADSKSync(const GpgKeyPtr& key, const GpgSubKey& adsk) -> std::tuple; private: diff --git a/src/core/function/gpg/GpgUIDOperator.cpp b/src/core/function/gpg/GpgUIDOperator.cpp index f3e4fcc2..a951fa6f 100644 --- a/src/core/function/gpg/GpgUIDOperator.cpp +++ b/src/core/function/gpg/GpgUIDOperator.cpp @@ -37,29 +37,29 @@ namespace GpgFrontend { GpgUIDOperator::GpgUIDOperator(int channel) : SingletonFunctionObject(channel) {} -auto GpgUIDOperator::AddUID(const GpgKey& key, const QString& uid) -> bool { +auto GpgUIDOperator::AddUID(const GpgKeyPtr& key, const QString& uid) -> bool { auto err = gpgme_op_adduid(ctx_.DefaultContext(), - static_cast(key), uid.toUtf8(), 0); + static_cast(*key), uid.toUtf8(), 0); return CheckGpgError(err) == GPG_ERR_NO_ERROR; } -auto GpgUIDOperator::SetPrimaryUID(const GpgKey& key, +auto GpgUIDOperator::SetPrimaryUID(const GpgKeyPtr& key, const QString& uid) -> bool { auto err = CheckGpgError(gpgme_op_set_uid_flag( - ctx_.DefaultContext(), static_cast(key), uid.toUtf8(), + ctx_.DefaultContext(), static_cast(*key), uid.toUtf8(), "primary", nullptr)); return CheckGpgError(err) == GPG_ERR_NO_ERROR; } -auto GpgUIDOperator::AddUID(const GpgKey& key, const QString& name, +auto GpgUIDOperator::AddUID(const GpgKeyPtr& key, const QString& name, const QString& comment, const QString& email) -> bool { LOG_D() << "new uuid:" << name << comment << email; return AddUID(key, QString("%1(%2)<%3>").arg(name).arg(comment).arg(email)); } -auto GpgUIDOperator::DeleteUID(const GpgKey& key, int uid_index) -> bool { - if (uid_index < 2 || uid_index > static_cast(key.UIDs().size())) { +auto GpgUIDOperator::DeleteUID(const GpgKeyPtr& key, int uid_index) -> bool { + if (uid_index < 2 || uid_index > static_cast(key->UIDs().size())) { LOG_W() << "illegal uid_index index: " << uid_index; return false; } @@ -131,7 +131,7 @@ auto GpgUIDOperator::DeleteUID(const GpgKey& key, int uid_index) -> bool { return QString(""); }; - auto key_fpr = key.Fingerprint(); + auto key_fpr = key->Fingerprint(); AutomatonHandelStruct handel_struct(key_fpr); handel_struct.SetHandler(next_state_handler, action_handler); @@ -141,10 +141,10 @@ auto GpgUIDOperator::DeleteUID(const GpgKey& key, int uid_index) -> bool { .DoInteract(key, next_state_handler, action_handler); } -auto GpgUIDOperator::RevokeUID(const GpgKey& key, int uid_index, +auto GpgUIDOperator::RevokeUID(const GpgKeyPtr& key, int uid_index, int reason_code, const QString& reason_text) -> bool { - if (uid_index < 2 || uid_index > static_cast(key.UIDs().size())) { + if (uid_index < 2 || uid_index > static_cast(key->UIDs().size())) { LOG_W() << "illegal uid index: " << uid_index; return false; } @@ -253,7 +253,7 @@ auto GpgUIDOperator::RevokeUID(const GpgKey& key, int uid_index, return QString(""); }; - auto key_fpr = key.Fingerprint(); + auto key_fpr = key->Fingerprint(); AutomatonHandelStruct handel_struct(key_fpr); handel_struct.SetHandler(next_state_handler, action_handler); diff --git a/src/core/function/gpg/GpgUIDOperator.h b/src/core/function/gpg/GpgUIDOperator.h index f0e925ed..e5e2f190 100644 --- a/src/core/function/gpg/GpgUIDOperator.h +++ b/src/core/function/gpg/GpgUIDOperator.h @@ -53,7 +53,7 @@ class GPGFRONTEND_CORE_EXPORT GpgUIDOperator * @param uid uid args(combine name&comment&email) * @return if successful */ - auto AddUID(const GpgKey& key, const QString& uid) -> bool; + auto AddUID(const GpgKeyPtr& key, const QString& uid) -> bool; /** * create a new uid in certain key pair @@ -63,7 +63,7 @@ class GPGFRONTEND_CORE_EXPORT GpgUIDOperator * @param email * @return */ - auto AddUID(const GpgKey& key, const QString& name, const QString& comment, + auto AddUID(const GpgKeyPtr& key, const QString& name, const QString& comment, const QString& email) -> bool; /** @@ -74,7 +74,7 @@ class GPGFRONTEND_CORE_EXPORT GpgUIDOperator * @return true * @return false */ - auto DeleteUID(const GpgKey& key, int uid_index) -> bool; + auto DeleteUID(const GpgKeyPtr& key, int uid_index) -> bool; /** * @brief @@ -86,7 +86,7 @@ class GPGFRONTEND_CORE_EXPORT GpgUIDOperator * @return true * @return false */ - auto RevokeUID(const GpgKey& key, int uid_index, int reason_code, + auto RevokeUID(const GpgKeyPtr& key, int uid_index, int reason_code, const QString& reason_text) -> bool; /** @@ -95,7 +95,7 @@ class GPGFRONTEND_CORE_EXPORT GpgUIDOperator * @param uid target uid * @return if successful */ - auto SetPrimaryUID(const GpgKey& key, const QString& uid) -> bool; + auto SetPrimaryUID(const GpgKeyPtr& key, const QString& uid) -> bool; private: GpgContext& ctx_ = diff --git a/src/core/function/result_analyse/GpgVerifyResultAnalyse.h b/src/core/function/result_analyse/GpgVerifyResultAnalyse.h index 719bb107..7166ae4d 100644 --- a/src/core/function/result_analyse/GpgVerifyResultAnalyse.h +++ b/src/core/function/result_analyse/GpgVerifyResultAnalyse.h @@ -29,6 +29,7 @@ #pragma once #include "GpgResultAnalyse.h" +#include "core/model/GpgSignature.h" #include "core/model/GpgVerifyResult.h" namespace GpgFrontend { diff --git a/src/core/model/DataObject.h b/src/core/model/DataObject.h index a2b19413..efd75c16 100644 --- a/src/core/model/DataObject.h +++ b/src/core/model/DataObject.h @@ -95,4 +95,8 @@ auto ExtractParams(const std::shared_ptr& d_o, int index) -> T { void swap(DataObject& a, DataObject& b) noexcept; +using DataObjectPtr = std::shared_ptr; ///< +using OperaRunnable = std::function; +using OperationCallback = std::function; + } // namespace GpgFrontend \ No newline at end of file diff --git a/src/core/model/GpgAbstractKey.h b/src/core/model/GpgAbstractKey.h index 854297bc..2789fa39 100644 --- a/src/core/model/GpgAbstractKey.h +++ b/src/core/model/GpgAbstractKey.h @@ -30,11 +30,22 @@ namespace GpgFrontend { +enum class GpgAbstractKeyType : unsigned int { + kNONE = 0, + kGPG_KEY, + kGPG_SUBKEY, + kGPG_KEYGROUP, +}; + class GpgAbstractKey { public: [[nodiscard]] virtual auto ID() const -> QString = 0; [[nodiscard]] virtual auto Fingerprint() const -> QString = 0; - [[nodiscard]] virtual auto IsSubKey() const -> bool = 0; + [[nodiscard]] virtual auto KeyType() const -> GpgAbstractKeyType = 0; + + [[nodiscard]] virtual auto Name() const -> QString = 0; + [[nodiscard]] virtual auto Email() const -> QString = 0; + [[nodiscard]] virtual auto Comment() const -> QString = 0; [[nodiscard]] virtual auto IsPrivateKey() const -> bool = 0; [[nodiscard]] virtual auto IsHasEncrCap() const -> bool = 0; @@ -54,6 +65,10 @@ class GpgAbstractKey { [[nodiscard]] auto IsPrimaryKey() const -> bool { return IsHasCertCap(); } + [[nodiscard]] virtual auto UID() const -> QString { + return QString("%1(%2)<%3>").arg(Name()).arg(Comment()).arg(Email()); + }; + auto operator==(const GpgAbstractKey& o) const -> bool { return ID() == o.ID(); } diff --git a/src/core/model/GpgKey.cpp b/src/core/model/GpgKey.cpp index 3efb53fc..1a7b7961 100644 --- a/src/core/model/GpgKey.cpp +++ b/src/core/model/GpgKey.cpp @@ -220,6 +220,8 @@ auto GpgKey::PrimaryKey() const -> GpgSubKey { return GpgSubKey(key_ref_, key_ref_->subkeys); } -auto GpgKey::IsSubKey() const -> bool { return false; } +auto GpgKey::KeyType() const -> GpgAbstractKeyType { + return GpgAbstractKeyType::kGPG_KEY; +} } // namespace GpgFrontend \ No newline at end of file diff --git a/src/core/model/GpgKey.h b/src/core/model/GpgKey.h index de2e8370..43410acd 100644 --- a/src/core/model/GpgKey.h +++ b/src/core/model/GpgKey.h @@ -28,12 +28,9 @@ #pragma once -#include - #include "core/model/GpgAbstractKey.h" #include "core/model/GpgSubKey.h" #include "core/model/GpgUID.h" - namespace GpgFrontend { /** @@ -98,7 +95,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKey : public GpgAbstractKey { * @return true * @return false */ - [[nodiscard]] auto IsSubKey() const -> bool override; + [[nodiscard]] auto KeyType() const -> GpgAbstractKeyType override; /** * @brief @@ -120,21 +117,21 @@ class GPGFRONTEND_CORE_EXPORT GpgKey : public GpgAbstractKey { * * @return QString */ - [[nodiscard]] auto Name() const -> QString; + [[nodiscard]] auto Name() const -> QString override; /** * @brief * * @return QString */ - [[nodiscard]] auto Email() const -> QString; + [[nodiscard]] auto Email() const -> QString override; /** * @brief * * @return QString */ - [[nodiscard]] auto Comment() const -> QString; + [[nodiscard]] auto Comment() const -> QString override; /** * @brief diff --git a/src/core/model/GpgKeyGroup.cpp b/src/core/model/GpgKeyGroup.cpp new file mode 100644 index 00000000..b572deac --- /dev/null +++ b/src/core/model/GpgKeyGroup.cpp @@ -0,0 +1,120 @@ +/** + * Copyright (C) 2021-2024 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend 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 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend 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 GpgFrontend. If not, see . + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "core/model/GpgKeyGroup.h" + +#include + +namespace GpgFrontend { + +GpgKeyGroup::GpgKeyGroup() = default; + +GpgKeyGroup::GpgKeyGroup(const GpgKeyGroup &) = default; + +GpgKeyGroup::~GpgKeyGroup() = default; + +auto GpgKeyGroup::operator=(const GpgKeyGroup &) -> GpgKeyGroup & = default; + +auto GpgKeyGroup::IsGood() const -> bool { return true; } + +auto GpgKeyGroup::ID() const -> QString { return id_; } + +auto GpgKeyGroup::Name() const -> QString { return name_; }; + +auto GpgKeyGroup::Email() const -> QString { return email_; } + +auto GpgKeyGroup::Comment() const -> QString { return comment_; } + +auto GpgKeyGroup::Fingerprint() const -> QString { return {}; } + +auto GpgKeyGroup::PublicKeyAlgo() const -> QString { return {}; } + +auto GpgKeyGroup::Algo() const -> QString { return {}; } + +auto GpgKeyGroup::ExpirationTime() const -> QDateTime { return {}; }; + +auto GpgKeyGroup::CreationTime() const -> QDateTime { return creation_time_; }; + +auto GpgKeyGroup::IsHasEncrCap() const -> bool { return true; } + +auto GpgKeyGroup::IsHasSignCap() const -> bool { return false; } + +auto GpgKeyGroup::IsHasCertCap() const -> bool { return false; } + +auto GpgKeyGroup::IsHasAuthCap() const -> bool { return false; } + +auto GpgKeyGroup::IsPrivateKey() const -> bool { return false; } + +auto GpgKeyGroup::IsExpired() const -> bool { return false; } + +auto GpgKeyGroup::IsRevoked() const -> bool { return false; } + +auto GpgKeyGroup::IsDisabled() const -> bool { + return key_ids_.isEmpty() || disabled_; +} + +auto GpgKeyGroup::KeyType() const -> GpgAbstractKeyType { + return GpgAbstractKeyType::kGPG_KEYGROUP; +} + +GpgKeyGroup::GpgKeyGroup(QString name, QString email, QString comment, + QStringList key_ids) + : id_("#&" + QUuid::createUuid().toRfc4122().toHex().left(14).toUpper()), + name_(std::move(name)), + email_(std::move(email)), + comment_(std::move(comment)), + key_ids_(std::move(key_ids)), + creation_time_(QDateTime::currentDateTime()) {} + +GpgKeyGroup::GpgKeyGroup(const KeyGroupCO &kg_co) + : id_(kg_co.id), + name_(kg_co.name), + email_(kg_co.email), + comment_(kg_co.comment), + key_ids_(kg_co.key_ids), + creation_time_(kg_co.creation_time) {} + +auto GpgKeyGroup::ToCacheObject() const -> KeyGroupCO { + KeyGroupCO co; + co.id = id_; + co.name = name_; + co.email = email_; + co.comment = comment_; + co.key_ids = key_ids_; + co.creation_time = creation_time_; + return co; +} + +auto GpgKeyGroup::KeyIds() const -> QStringList { return key_ids_; } + +void GpgKeyGroup::SetKeyIds(QStringList key_ids) { + key_ids_ = std::move(key_ids); +} + +void GpgKeyGroup::SetDisabled(bool disabled) { disabled_ = disabled; } +} // namespace GpgFrontend \ No newline at end of file diff --git a/src/core/model/GpgKeyGroup.h b/src/core/model/GpgKeyGroup.h new file mode 100644 index 00000000..d3ae8e03 --- /dev/null +++ b/src/core/model/GpgKeyGroup.h @@ -0,0 +1,263 @@ +/** + * Copyright (C) 2021-2024 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend 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 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend 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 GpgFrontend. If not, see . + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#pragma once + +#include "core/model/GpgAbstractKey.h" +#include "core/struct/cache_object/KeyGroupCO.h" + +namespace GpgFrontend { + +/** + * @brief + * + */ +class GPGFRONTEND_CORE_EXPORT GpgKeyGroup : public GpgAbstractKey { + public: + /** + * @brief Construct a new Gpg Key object + * + */ + GpgKeyGroup(); + + /** + * @brief Construct a new Gpg Key object + * + * @param key + */ + GpgKeyGroup(QString name, QString email, QString comment, + QStringList key_ids); + + /** + * @brief Construct a new Gpg Key Group object + * + * @param kg_co + */ + explicit GpgKeyGroup(const KeyGroupCO& kg_co); + + /** + * @brief Construct a new Gpg Key object + * + * @param k + */ + GpgKeyGroup(const GpgKeyGroup&); + + /** + * @brief Destroy the Gpg Key objects + * + */ + virtual ~GpgKeyGroup() override; + + /** + * @brief + * + * @param k + * @return GpgKey& + */ + auto operator=(const GpgKeyGroup&) -> GpgKeyGroup&; + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] auto KeyType() const -> GpgAbstractKeyType override; + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] auto IsGood() const -> bool override; + + /** + * @brief + * + * @return QString + */ + [[nodiscard]] auto ID() const -> QString override; + + /** + * @brief + * + * @return QString + */ + [[nodiscard]] auto Name() const -> QString override; + + /** + * @brief + * + * @return QString + */ + [[nodiscard]] auto Email() const -> QString override; + + /** + * @brief + * + * @return QString + */ + [[nodiscard]] auto Comment() const -> QString override; + + /** + * @brief + * + * @return QString + */ + [[nodiscard]] auto Fingerprint() const -> QString override; + + /** + * @brief + * + * @return QString + */ + [[nodiscard]] auto PublicKeyAlgo() const -> QString override; + + /** + * @brief + * + * @return QString + */ + [[nodiscard]] auto Algo() const -> QString override; + + /** + * @brief + * + * @return QDateTime + */ + [[nodiscard]] auto ExpirationTime() const -> QDateTime override; + + /** + * @brief Create a time object + * + * @return QDateTime + */ + [[nodiscard]] auto CreationTime() const -> QDateTime override; + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] auto IsHasEncrCap() const -> bool override; + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] auto IsHasSignCap() const -> bool override; + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] auto IsHasCertCap() const -> bool override; + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] auto IsHasAuthCap() const -> bool override; + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] auto IsPrivateKey() const -> bool override; + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] auto IsExpired() const -> bool override; + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] auto IsRevoked() const -> bool override; + + /** + * @brief + * + * @return true + * @return false + */ + [[nodiscard]] auto IsDisabled() const -> bool override; + + /** + * @brief + * + * @return KeyGroupCO + */ + [[nodiscard]] auto ToCacheObject() const -> KeyGroupCO; + + /** + * @brief + * + * @return KeyGroupCO + */ + [[nodiscard]] auto KeyIds() const -> QStringList; + + /** + * @brief Set the Key Ids object + * + */ + void SetKeyIds(QStringList); + + /** + * @brief Set the Disabled object + * + */ + void SetDisabled(bool); + + private: + QString id_; + QString name_; + QString email_; + QString comment_; + QStringList key_ids_; + QDateTime creation_time_; + bool disabled_; +}; + +} // namespace GpgFrontend diff --git a/src/core/model/GpgKeySignature.h b/src/core/model/GpgKeySignature.h index 5f190fa2..94870e0f 100644 --- a/src/core/model/GpgKeySignature.h +++ b/src/core/model/GpgKeySignature.h @@ -28,12 +28,11 @@ #pragma once -#include "core/typedef/GpgTypedef.h" - /** * @brief * */ +#include "core/typedef/GpgErrorTypedef.h" namespace GpgFrontend { /** diff --git a/src/core/model/GpgKeyTableModel.cpp b/src/core/model/GpgKeyTableModel.cpp index 858ebd75..db456431 100644 --- a/src/core/model/GpgKeyTableModel.cpp +++ b/src/core/model/GpgKeyTableModel.cpp @@ -28,12 +28,16 @@ #include "GpgKeyTableModel.h" +#include + #include "core/model/GpgKey.h" +#include "core/model/GpgKeyGroup.h" #include "core/utils/GpgUtils.h" namespace GpgFrontend { -GpgKeyTableModel::GpgKeyTableModel(int channel, GpgKeyList keys, +GpgKeyTableModel::GpgKeyTableModel(int channel, + const GpgAbstractKeyPtrList &keys, QObject *parent) : QAbstractTableModel(parent), column_headers_({tr("Select"), tr("Type"), tr("Name"), @@ -61,6 +65,123 @@ auto GpgKeyTableModel::columnCount(const QModelIndex & /*parent*/) const return 11; } +auto GpgKeyTableModel::table_data_by_gpg_key(const QModelIndex &index, + const GpgKey *key) -> QVariant { + switch (index.column()) { + case 0: { + return index.row(); + } + case 1: { + QString type_sym; + type_sym += key->IsPrivateKey() ? "pub/sec" : "pub"; + if (key->IsPrivateKey() && !key->IsHasMasterKey()) type_sym += "#"; + if (key->IsHasCardKey()) type_sym += "^"; + return type_sym; + } + case 2: { + return key->Name(); + } + case 3: { + return key->Email(); + } + case 4: { + return GetUsagesByAbstractKey(key); + } + case 5: { + return key->OwnerTrust(); + } + case 6: { + return key->ID(); + } + case 7: { + return QLocale().toString(key->CreationTime(), "yyyy-MM-dd"); + } + case 8: { + return key->Algo(); + } + case 9: { + return static_cast(key->SubKeys().size()); + } + case 10: { + return key->Comment(); + } + default: + return {}; + } +} + +auto GpgKeyTableModel::table_data_by_gpg_key_group( + const QModelIndex &index, const GpgKeyGroup *kg) -> QVariant { + switch (index.column()) { + case 0: { + return index.row(); + } + case 1: { + return "group"; + } + case 2: { + return kg->Name(); + } + case 3: { + return kg->Email(); + } + case 4: { + return GetUsagesByAbstractKey(kg); + } + case 5: { + return "/"; + } + case 6: { + return kg->ID(); + } + case 7: { + return QLocale().toString(kg->CreationTime(), "yyyy-MM-dd"); + } + case 8: { + return kg->Algo(); + } + case 9: { + return static_cast(kg->KeyIds().size()); + } + case 10: { + return kg->Comment(); + } + default: + return {}; + } +} + +auto GpgKeyTableModel::table_tooltip_by_gpg_key( + const QModelIndex & /*index*/, const GpgKey *key) const -> QVariant { + QStringList tooltip_lines; + tooltip_lines << tr("ID: %1").arg(key->ID()); + tooltip_lines << tr("Algo: %1").arg(key->Algo()); + tooltip_lines << tr("Usage: %1").arg(GetUsagesByAbstractKey(key)); + tooltip_lines << tr("Trust: %1").arg(key->OwnerTrust()); + tooltip_lines << tr("Comment: %1") + .arg(key->Comment().isEmpty() + ? "<" + tr("No Comment") + ">" + : key->Comment()); + + const auto s_keys = key->SubKeys(); + if (!s_keys.empty()) { + tooltip_lines << ""; + tooltip_lines << tr("SubKeys (up to 8):"); + + int count = 0; + for (const auto &s_key : s_keys) { + if (count++ >= 8) break; + const auto usages = GetUsagesByAbstractKey(&s_key); + tooltip_lines << tr(" - ID: %1 | Algo: %2 | Usage: %3") + .arg(s_key.ID()) + .arg(s_key.Algo()) + .arg(usages.trimmed()); + } + } + + return tooltip_lines.join("\n"); +} + auto GpgKeyTableModel::data(const QModelIndex &index, int role) const -> QVariant { if (!index.isValid() || cached_items_.empty()) return {}; @@ -77,47 +198,16 @@ auto GpgKeyTableModel::data(const QModelIndex &index, } if (role == Qt::DisplayRole) { - const auto key = i->Key(); + auto *key = i->Key(); + switch (key->KeyType()) { + case GpgAbstractKeyType::kGPG_KEY: + return table_data_by_gpg_key(index, dynamic_cast(key)); + case GpgAbstractKeyType::kGPG_KEYGROUP: + return table_data_by_gpg_key_group(index, + dynamic_cast(key)); + case GpgAbstractKeyType::kNONE: + case GpgAbstractKeyType::kGPG_SUBKEY: - switch (index.column()) { - case 0: { - return index.row(); - } - case 1: { - QString type_sym; - type_sym += key.IsPrivateKey() ? "pub/sec" : "pub"; - if (key.IsPrivateKey() && !key.IsHasMasterKey()) type_sym += "#"; - if (key.IsHasCardKey()) type_sym += "^"; - return type_sym; - } - case 2: { - return key.Name(); - } - case 3: { - return key.Email(); - } - case 4: { - return GetUsagesByKey(key); - } - case 5: { - return key.OwnerTrust(); - } - case 6: { - return key.ID(); - } - case 7: { - return QLocale().toString(key.CreationTime(), "yyyy-MM-dd"); - } - case 8: { - return key.Algo(); - } - case 9: { - return static_cast(key.SubKeys().size()); - } - case 10: { - return key.Comment(); - } - default: return {}; } } @@ -138,35 +228,24 @@ auto GpgKeyTableModel::data(const QModelIndex &index, } if (role == Qt::ToolTipRole) { - const auto key = i->Key(); - - QStringList tooltip_lines; - tooltip_lines << tr("ID: %1").arg(key.ID()); - tooltip_lines << tr("Algo: %1").arg(key.Algo()); - tooltip_lines << tr("Usage: %1").arg(GetUsagesByKey(key)); - tooltip_lines << tr("Trust: %1").arg(key.OwnerTrust()); - tooltip_lines << tr("Comment: %1") - .arg(key.Comment().isEmpty() - ? "<" + tr("No Comment") + ">" - : key.Comment()); - - const auto s_keys = key.SubKeys(); - if (!s_keys.empty()) { - tooltip_lines << ""; - tooltip_lines << tr("SubKeys (up to 8):"); - - int count = 0; - for (const auto &s_key : s_keys) { - if (count++ >= 8) break; - const auto usages = GetUsagesBySubkey(s_key); - tooltip_lines << tr(" - ID: %1 | Algo: %2 | Usage: %3") - .arg(s_key.ID()) - .arg(s_key.Algo()) - .arg(usages.trimmed()); - } - } - - return tooltip_lines.join("\n"); + auto *const key = i->Key(); + switch (key->KeyType()) { + case GpgAbstractKeyType::kGPG_KEY: + return table_tooltip_by_gpg_key(index, dynamic_cast(key)); + case GpgAbstractKeyType::kNONE: + case GpgAbstractKeyType::kGPG_SUBKEY: + case GpgAbstractKeyType::kGPG_KEYGROUP: + return {}; + } + } + + if (role == Qt::BackgroundRole) { + auto *const key = i->Key(); + if (key->IsDisabled()) return QColorConstants::DarkRed; + if (key->IsExpired() || key->IsRevoked()) { + return QColorConstants::DarkYellow; + } + return {}; } return {}; @@ -194,50 +273,41 @@ auto GpgKeyTableModel::flags(const QModelIndex &index) const -> Qt::ItemFlags { auto GpgKeyTableModel::setData(const QModelIndex &index, const QVariant &value, int role) -> bool { - if (!index.isValid()) return false; + if (!index.isValid() || index.column() != 0 || role != Qt::CheckStateRole) { + return false; + } - auto *i = index.isValid() - ? static_cast(index.internalPointer()) - : nullptr; + auto *i = static_cast(index.internalPointer()); if (i == nullptr) return false; - if (index.column() == 0 && role == Qt::CheckStateRole) { - i->SetChecked(value == Qt::Checked); - emit dataChanged(index, index); - return true; - } + const bool state = (value.toInt() == Qt::Checked); + if (i->Checked() == state) return false; + i->SetChecked(state); - return false; + emit dataChanged(index, index, {Qt::CheckStateRole}); + return true; } -auto GpgKeyTableModel::GetAllKeyIds() -> KeyIdArgsList { - KeyIdArgsList keys; - for (auto &i : cached_items_) { - keys.push_back(i.Key().ID()); +auto GpgKeyTableModel::GetAllKeys() const -> GpgAbstractKeyPtrList { + GpgAbstractKeyPtrList keys; + for (const auto &i : cached_items_) { + keys.push_back(i.SharedKey()); } return keys; } -auto GpgKeyTableModel::GetKeyIDByRow(int row) const -> QString { - if (cached_items_.size() <= row) return {}; - - return cached_items_[row].Key().ID(); -} - -auto GpgKeyTableModel::IsPrivateKeyByRow(int row) const -> bool { - if (cached_items_.size() <= row) return false; - return cached_items_[row].Key().IsPrivateKey(); -} - auto GpgKeyTableModel::GetGpgContextChannel() const -> int { return gpg_context_channel_; } -GpgKeyTableItem::GpgKeyTableItem(const GpgKey &key) : key_(key) {} +GpgKeyTableItem::GpgKeyTableItem(GpgAbstractKeyPtr key) + : key_(std::move(key)) {} GpgKeyTableItem::GpgKeyTableItem(const GpgKeyTableItem &) = default; -auto GpgKeyTableItem::Key() const -> GpgKey { return key_; } +auto GpgKeyTableItem::Key() const -> GpgAbstractKey * { return key_.get(); } + +auto GpgKeyTableItem::SharedKey() const -> GpgAbstractKeyPtr { return key_; } void GpgKeyTableItem::SetChecked(bool checked) { checked_ = checked; } diff --git a/src/core/model/GpgKeyTableModel.h b/src/core/model/GpgKeyTableModel.h index 69118f56..d5cecf14 100644 --- a/src/core/model/GpgKeyTableModel.h +++ b/src/core/model/GpgKeyTableModel.h @@ -32,11 +32,13 @@ * @brief * */ -#include "core/model/GpgKey.h" #include "core/typedef/GpgTypedef.h" namespace GpgFrontend { +class GpgKey; +class GpgKeyGroup; + enum class GpgKeyTableColumn : unsigned int { kNONE = 0, kTYPE = 1 << 0, @@ -114,11 +116,23 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyTableItem { public: GpgKeyTableItem() = default; - explicit GpgKeyTableItem(const GpgKey &key); + explicit GpgKeyTableItem(GpgAbstractKeyPtr key); GpgKeyTableItem(const GpgKeyTableItem &); - [[nodiscard]] auto Key() const -> GpgKey; + /** + * @brief + * + * @return GpgAbstractKey* + */ + [[nodiscard]] auto Key() const -> GpgAbstractKey *; + + /** + * @brief + * + * @return GpgAbstractKeyPtr + */ + [[nodiscard]] auto SharedKey() const -> GpgAbstractKeyPtr; /** * @brief @@ -136,7 +150,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyTableItem { void SetChecked(bool); private: - GpgKey key_; + GpgAbstractKeyPtr key_; bool checked_; }; @@ -149,7 +163,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyTableModel : public QAbstractTableModel { * @param keys * @param parent */ - explicit GpgKeyTableModel(int channel, GpgKeyList keys, + explicit GpgKeyTableModel(int channel, const GpgAbstractKeyPtrList &keys, QObject *parent = nullptr); /** @@ -227,23 +241,7 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyTableModel : public QAbstractTableModel { * * @return auto */ - auto GetAllKeyIds() -> KeyIdArgsList; - - /** - * @brief Get the Key ID By Row object - * - * @return QString - */ - [[nodiscard]] auto GetKeyIDByRow(int row) const -> QString; - - /** - * @brief - * - * @param row - * @return true - * @return false - */ - [[nodiscard]] auto IsPrivateKeyByRow(int row) const -> bool; + [[nodiscard]] auto GetAllKeys() const -> GpgAbstractKeyPtrList; /** * @brief @@ -256,6 +254,15 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyTableModel : public QAbstractTableModel { QStringList column_headers_; int gpg_context_channel_; + auto table_tooltip_by_gpg_key(const QModelIndex &index, + const GpgKey *key) const -> QVariant; + + static auto table_data_by_gpg_key(const QModelIndex &index, + const GpgKey *key) -> QVariant; + + static auto table_data_by_gpg_key_group(const QModelIndex &index, + const GpgKeyGroup *kg) -> QVariant; + QContainer cached_items_; }; diff --git a/src/core/model/GpgKeyTreeModel.cpp b/src/core/model/GpgKeyTreeModel.cpp index bbe5d00b..a62878c9 100644 --- a/src/core/model/GpgKeyTreeModel.cpp +++ b/src/core/model/GpgKeyTreeModel.cpp @@ -211,7 +211,7 @@ auto GpgKeyTreeModel::create_gpg_key_tree_items(const GpgKey &key) columns << key.UIDs().front().GetUID(); columns << key.ID(); - columns << GetUsagesByKey(key); + columns << GetUsagesByAbstractKey(&key); columns << key.PublicKeyAlgo(); columns << key.Algo(); columns << QLocale().toString(key.CreationTime(), "yyyy-MM-dd"); @@ -228,7 +228,7 @@ auto GpgKeyTreeModel::create_gpg_key_tree_items(const GpgKey &key) columns << (s_key.IsHasCertCap() ? "primary" : "sub"); columns << key.UIDs().front().GetUID(); columns << s_key.ID(); - columns << GetUsagesBySubkey(s_key); + columns << GetUsagesByAbstractKey(&s_key); columns << s_key.PublicKeyAlgo(); columns << s_key.Algo(); columns << QLocale().toString(s_key.CreationTime(), "yyyy-MM-dd"); @@ -247,7 +247,10 @@ auto GpgKeyTreeModel::create_gpg_key_tree_items(const GpgKey &key) auto GpgKeyTreeModel::GetAllCheckedSubKey() -> QContainer { QContainer ret; for (const auto &i : cached_items_) { - if (!i->Key()->IsSubKey() || !i->Checkable() || !i->Checked()) continue; + if (i->Key()->KeyType() != GpgAbstractKeyType::kGPG_SUBKEY || + !i->Checkable() || !i->Checked()) { + continue; + } auto *s_key = dynamic_cast(i->Key()); if (s_key == nullptr) continue; @@ -315,6 +318,8 @@ void GpgKeyTreeItem::SetCheckable(bool checkable) { checkable_ = checkable; } auto GpgKeyTreeItem::Key() const -> GpgAbstractKey * { return key_.get(); } +auto GpgKeyTreeItem::SharedKey() const -> GpgAbstractKeyPtr { return key_; } + auto GpgKeyTreeItem::Enable() const -> bool { return enable_; } void GpgKeyTreeItem::SetEnable(bool enable) { enable_ = enable; } diff --git a/src/core/model/GpgKeyTreeModel.h b/src/core/model/GpgKeyTreeModel.h index 9e91037d..20b63e01 100644 --- a/src/core/model/GpgKeyTreeModel.h +++ b/src/core/model/GpgKeyTreeModel.h @@ -222,6 +222,13 @@ class GPGFRONTEND_CORE_EXPORT GpgKeyTreeItem { */ [[nodiscard]] auto Key() const -> GpgAbstractKey *; + /** + * @brief + * + * @return GpgAbstractKeyPtr + */ + [[nodiscard]] auto SharedKey() const -> GpgAbstractKeyPtr; + private: QContainer> children_; QVariantList data_; diff --git a/src/core/model/GpgSubKey.cpp b/src/core/model/GpgSubKey.cpp index a4e6582f..38710ead 100644 --- a/src/core/model/GpgSubKey.cpp +++ b/src/core/model/GpgSubKey.cpp @@ -95,11 +95,20 @@ auto GpgSubKey::SmartCardSerialNumber() const -> QString { return QString::fromLatin1(s_key_ref_->card_number); } -auto GpgSubKey::IsSubKey() const -> bool { return true; } +auto GpgSubKey::KeyType() const -> GpgAbstractKeyType { + return GpgAbstractKeyType::kGPG_SUBKEY; +} auto GpgSubKey::IsGood() const -> bool { return s_key_ref_ != nullptr; } auto GpgSubKey::Convert2GpgKey() const -> QSharedPointer { return QSharedPointer::create(key_ref_); } + +auto GpgSubKey::Name() const -> QString { return key_ref_->uids->name; } + +auto GpgSubKey::Email() const -> QString { return key_ref_->uids->email; } + +auto GpgSubKey::Comment() const -> QString { return key_ref_->uids->comment; } + } // namespace GpgFrontend diff --git a/src/core/model/GpgSubKey.h b/src/core/model/GpgSubKey.h index c947b8af..920f42e8 100644 --- a/src/core/model/GpgSubKey.h +++ b/src/core/model/GpgSubKey.h @@ -96,7 +96,7 @@ class GPGFRONTEND_CORE_EXPORT GpgSubKey : public GpgAbstractKey { * @return true * @return false */ - [[nodiscard]] auto IsSubKey() const -> bool override; + [[nodiscard]] auto KeyType() const -> GpgAbstractKeyType override; /** * @brief @@ -106,6 +106,27 @@ class GPGFRONTEND_CORE_EXPORT GpgSubKey : public GpgAbstractKey { */ [[nodiscard]] auto IsGood() const -> bool override; + /** + * @brief + * + * @return QString + */ + [[nodiscard]] auto Name() const -> QString override; + + /** + * @brief + * + * @return QString + */ + [[nodiscard]] auto Email() const -> QString override; + + /** + * @brief + * + * @return QString + */ + [[nodiscard]] auto Comment() const -> QString override; + /** * @brief * diff --git a/src/core/model/GpgUID.h b/src/core/model/GpgUID.h index 49ddd4c4..6cc44b57 100644 --- a/src/core/model/GpgUID.h +++ b/src/core/model/GpgUID.h @@ -28,8 +28,9 @@ #pragma once -#include "GpgKeySignature.h" #include "GpgTOFUInfo.h" +#include "core/model/GpgKeySignature.h" +#include "core/typedef/CoreTypedef.h" namespace GpgFrontend { /** diff --git a/src/core/model/GpgVerifyResult.h b/src/core/model/GpgVerifyResult.h index c150d633..6e61497e 100644 --- a/src/core/model/GpgVerifyResult.h +++ b/src/core/model/GpgVerifyResult.h @@ -29,7 +29,7 @@ #pragma once #include "core/GpgFrontendCoreExport.h" -#include "core/typedef/GpgTypedef.h" +#include "core/model/GpgSignature.h" namespace GpgFrontend { diff --git a/src/core/struct/cache_object/KeyGroupCO.h b/src/core/struct/cache_object/KeyGroupCO.h new file mode 100644 index 00000000..6d113a52 --- /dev/null +++ b/src/core/struct/cache_object/KeyGroupCO.h @@ -0,0 +1,86 @@ +/** + * Copyright (C) 2021-2024 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend 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 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend 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 GpgFrontend. If not, see . + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#pragma once + +namespace GpgFrontend { + +struct KeyGroupCO { + QString id; + QString name; + QString email; + QString comment; + QDateTime creation_time; + QStringList key_ids; + + KeyGroupCO() = default; + + explicit KeyGroupCO(const QJsonObject& j) { + if (const auto v = j["id"]; v.isString()) { + id = v.toString(); + } + if (const auto v = j["name"]; v.isString()) { + name = v.toString(); + } + if (const auto v = j["email"]; v.isString()) { + email = v.toString(); + } + if (const auto v = j["comment"]; v.isString()) { + comment = v.toString(); + } + if (const auto v = j["creation_time"]; v.isDouble()) { + creation_time = QDateTime::fromSecsSinceEpoch(v.toInt()); + } + + if (!j.contains("key_ids") || !j["key_ids"].isArray()) return; + for (const auto& i : j["key_ids"].toArray()) { + if (!i.isString()) continue; + + key_ids.append(i.toString()); + } + } + + [[nodiscard]] auto ToJson() const -> QJsonObject { + QJsonObject j; + + j["id"] = id; + j["name"] = name; + j["email"] = email; + j["comment"] = comment; + j["creation_time"] = creation_time.toSecsSinceEpoch(); + + auto a = QJsonArray(); + for (const auto& k : key_ids) { + a.push_back(k); + } + j["key_ids"] = a; + return j; + } +}; + +} // namespace GpgFrontend \ No newline at end of file diff --git a/src/core/struct/cache_object/KeyGroupsCO.h b/src/core/struct/cache_object/KeyGroupsCO.h new file mode 100644 index 00000000..0bccdcec --- /dev/null +++ b/src/core/struct/cache_object/KeyGroupsCO.h @@ -0,0 +1,68 @@ +/** + * Copyright (C) 2021-2024 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend 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 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend 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 GpgFrontend. If not, see . + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#pragma once + +#include "KeyGroupCO.h" +#include "core/typedef/CoreTypedef.h" + +namespace GpgFrontend { + +struct KeyGroupsCO { + QContainer key_groups; + QString key_db_name; + + KeyGroupsCO() = default; + + explicit KeyGroupsCO(const QJsonObject& j) { + if (const auto v = j["key_db_name"]; v.isString()) { + key_db_name = v.toString(); + } + if (!j.contains("key_groups") || !j["key_groups"].isArray()) return; + for (const auto& i : j["key_groups"].toArray()) { + if (!i.isObject()) continue; + + key_groups.append(KeyGroupCO{i.toObject()}); + } + } + + [[nodiscard]] auto ToJson() const -> QJsonObject { + QJsonObject j; + + j["key_db_name"] = key_db_name; + + auto a = QJsonArray(); + for (const auto& k : key_groups) { + a.push_back(k.ToJson()); + } + j["key_groups"] = a; + return j; + } +}; + +} // namespace GpgFrontend \ No newline at end of file diff --git a/src/core/typedef/CoreTypedef.h b/src/core/typedef/CoreTypedef.h index 7d62cf20..3f7e4021 100644 --- a/src/core/typedef/CoreTypedef.h +++ b/src/core/typedef/CoreTypedef.h @@ -45,8 +45,4 @@ using BypeArrayConstRef = const ByteArray&; ///< using StringArgsPtr = QStringList; ///< using StringArgsRef = QStringList&; ///< -class DataObject; -using DataObjectPtr = std::shared_ptr; ///< -using OperaRunnable = std::function; -using OperationCallback = std::function; } // namespace GpgFrontend \ No newline at end of file diff --git a/src/core/typedef/GpgErrorTypedef.h b/src/core/typedef/GpgErrorTypedef.h new file mode 100644 index 00000000..85ee2b4a --- /dev/null +++ b/src/core/typedef/GpgErrorTypedef.h @@ -0,0 +1,39 @@ +/** + * Copyright (C) 2021-2024 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend 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 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend 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 GpgFrontend. If not, see . + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#pragma once + +#include + +namespace GpgFrontend { + +using GpgError = gpgme_error_t; +using GpgErrorCode = gpg_err_code_t; +using GpgErrorDesc = QPair; + +} // namespace GpgFrontend \ No newline at end of file diff --git a/src/core/typedef/GpgTypedef.h b/src/core/typedef/GpgTypedef.h index 8d9fbf5f..89de69b4 100644 --- a/src/core/typedef/GpgTypedef.h +++ b/src/core/typedef/GpgTypedef.h @@ -32,28 +32,27 @@ #include -#include "core/model/DataObject.h" #include "core/typedef/CoreTypedef.h" +#include "core/typedef/GpgErrorTypedef.h" -namespace GpgFrontend { - -class GpgKey; ///< forward declaration -class GpgSubKey; -class GpgSignature; -class GpgTOFUInfo; +// models +#include "core/model/DataObject.h" +#include "core/model/GpgKey.h" -using GpgError = gpgme_error_t; ///< gpgme error -using GpgErrorCode = gpg_err_code_t; -using GpgErrorDesc = QPair; +namespace GpgFrontend { using KeyId = QString; using SubkeyId = QString; -using KeyIdArgsList = QStringList; ///< -using UIDArgsList = QStringList; ///< -using SignIdArgsList = QContainer>; ///< -using KeyArgsList = QContainer; ///< -using GpgKeyLinkList = QContainer; ///< -using GpgKeyList = QContainer; ///< +using KeyIdArgsList = QStringList; ///< +using UIDArgsList = QStringList; ///< +using SignIdArgsList = QContainer>; ///< +using KeyArgsList = QContainer; ///< +using GpgKeyLinkList = QContainer; ///< +using GpgKeyList = QContainer; ///< +using GpgAbstractKeyPtr = QSharedPointer; ///< +using GpgAbstractKeyPtrList = QContainer; ///< +using GpgKeyPtr = QSharedPointer; ///< +using GpgKeyPtrList = QContainer; ///< using GpgSignMode = gpgme_sig_mode_t; diff --git a/src/core/utils/GpgUtils.cpp b/src/core/utils/GpgUtils.cpp index 22ba856e..ad93fe67 100644 --- a/src/core/utils/GpgUtils.cpp +++ b/src/core/utils/GpgUtils.cpp @@ -29,12 +29,13 @@ #include "GpgUtils.h" #include "core/function/GlobalSettingStation.h" +#include "core/function/gpg/GpgAbstractKeyGetter.h" #include "core/model/GpgKey.h" +#include "core/model/GpgKeyGroup.h" #include "core/model/KeyDatabaseInfo.h" #include "core/model/SettingsObject.h" #include "core/module/ModuleManager.h" #include "core/struct/settings_object/KeyDatabaseListSO.h" - namespace GpgFrontend { inline auto Trim(QString& s) -> QString { return s.trimmed(); } @@ -326,31 +327,65 @@ auto GetKeyDatabaseInfoBySettings() -> QContainer { return key_db_infos; } -auto GPGFRONTEND_CORE_EXPORT Convert2RawGpgMEKeyList( - const QContainer& keys) -> QContainer { - QContainer recipients(keys.begin(), keys.end()); - recipients.push_back(nullptr); +auto GPGFRONTEND_CORE_EXPORT ConvertKey2GpgKeyIdList( + int channel, const GpgAbstractKeyPtrList& keys) -> KeyIdArgsList { + KeyIdArgsList ret; + for (const auto& key : ConvertKey2GpgKeyList(channel, keys)) { + ret.push_back(key->ID()); + } + return ret; +} + +auto GPGFRONTEND_CORE_EXPORT ConvertKey2GpgKeyList( + int channel, const GpgAbstractKeyPtrList& keys) -> GpgKeyPtrList { + GpgKeyPtrList recipients; + + QSet s; + for (const auto& key : keys) { + if (key == nullptr || key->IsDisabled() || s.contains(key->ID())) continue; + + if (key->KeyType() == GpgAbstractKeyType::kGPG_KEY) { + recipients.push_back(qSharedPointerDynamicCast(key)); + } else if (key->KeyType() == GpgAbstractKeyType::kGPG_KEYGROUP) { + auto key_ids = qSharedPointerDynamicCast(key)->KeyIds(); + recipients += ConvertKey2GpgKeyList( + channel, GpgAbstractKeyGetter::GetInstance().GetKeys(key_ids)); + } + + s.insert(key->ID()); + } + + assert(std::all_of(keys.begin(), keys.end(), + [](const auto& key) { return key->IsGood(); })); return recipients; } -auto GPGFRONTEND_CORE_EXPORT GetUsagesByKey(const GpgKey& key) -> QString { - QString usages; - if (key.IsHasActualCertCap()) usages += "C"; - if (key.IsHasActualEncrCap()) usages += "E"; - if (key.IsHasActualSignCap()) usages += "S"; - if (key.IsHasActualAuthCap()) usages += "A"; - return usages; +auto GPGFRONTEND_CORE_EXPORT Convert2RawGpgMEKeyList( + int channel, const GpgAbstractKeyPtrList& keys) -> QContainer { + QContainer recipients; + + auto g_keys = ConvertKey2GpgKeyList(channel, keys); + for (const auto& key : g_keys) { + recipients.push_back( + static_cast(*qSharedPointerDynamicCast(key))); + } + + recipients.push_back(nullptr); + return recipients; } -auto GPGFRONTEND_CORE_EXPORT GetUsagesBySubkey(const GpgSubKey& key) +auto GPGFRONTEND_CORE_EXPORT GetUsagesByAbstractKey(const GpgAbstractKey* key) -> QString { QString usages; - if (key.IsHasCertCap()) usages += "C"; - if (key.IsHasEncrCap()) usages += "E"; - if (key.IsHasSignCap()) usages += "S"; - if (key.IsHasAuthCap()) usages += "A"; - if (key.IsADSK()) usages += "R"; + if (key->IsHasCertCap()) usages += "C"; + if (key->IsHasEncrCap()) usages += "E"; + if (key->IsHasSignCap()) usages += "S"; + if (key->IsHasAuthCap()) usages += "A"; + + if (key->KeyType() == GpgAbstractKeyType::kGPG_SUBKEY) { + if (dynamic_cast(key)->IsADSK()) usages += "R"; + } return usages; } @@ -358,7 +393,7 @@ auto GPGFRONTEND_CORE_EXPORT GetGpgKeyByGpgAbstractKey(GpgAbstractKey* ab_key) -> GpgKey { if (!ab_key->IsGood()) return {}; - if (ab_key->IsSubKey()) { + if (ab_key->KeyType() == GpgAbstractKeyType::kGPG_SUBKEY) { auto* s_key = dynamic_cast(ab_key); assert(s_key != nullptr); @@ -370,4 +405,9 @@ auto GPGFRONTEND_CORE_EXPORT GetGpgKeyByGpgAbstractKey(GpgAbstractKey* ab_key) auto* key = dynamic_cast(ab_key); return *key; } + +auto GPGFRONTEND_CORE_EXPORT IsKeyGroupID(const KeyId& id) -> bool { + return id.startsWith("#&"); +} + } // namespace GpgFrontend diff --git a/src/core/utils/GpgUtils.h b/src/core/utils/GpgUtils.h index 9fcfe5cf..13612b4f 100644 --- a/src/core/utils/GpgUtils.h +++ b/src/core/utils/GpgUtils.h @@ -151,19 +151,31 @@ auto GPGFRONTEND_CORE_EXPORT GetGpgKeyDatabaseName(int channel) -> QString; /** * @brief * + * @param channel * @param keys - * @return QContainer + * @return KeyIdArgsList */ -auto GPGFRONTEND_CORE_EXPORT Convert2RawGpgMEKeyList( - const QContainer& keys) -> QContainer; +auto GPGFRONTEND_CORE_EXPORT ConvertKey2GpgKeyIdList( + int channel, const GpgAbstractKeyPtrList& keys) -> KeyIdArgsList; /** * @brief * - * @param key - * @return QString + * @param channel + * @param keys + * @return GpgKeyPtrList */ -auto GPGFRONTEND_CORE_EXPORT GetUsagesByKey(const GpgKey& key) -> QString; +auto GPGFRONTEND_CORE_EXPORT ConvertKey2GpgKeyList( + int channel, const GpgAbstractKeyPtrList& keys) -> GpgKeyPtrList; + +/** + * @brief + * + * @param keys + * @return QContainer + */ +auto GPGFRONTEND_CORE_EXPORT Convert2RawGpgMEKeyList( + int channel, const GpgAbstractKeyPtrList& keys) -> QContainer; /** * @brief @@ -171,7 +183,8 @@ auto GPGFRONTEND_CORE_EXPORT GetUsagesByKey(const GpgKey& key) -> QString; * @param key * @return QString */ -auto GPGFRONTEND_CORE_EXPORT GetUsagesBySubkey(const GpgSubKey& key) -> QString; +auto GPGFRONTEND_CORE_EXPORT GetUsagesByAbstractKey(const GpgAbstractKey* key) + -> QString; /** * @brief @@ -181,4 +194,12 @@ auto GPGFRONTEND_CORE_EXPORT GetUsagesBySubkey(const GpgSubKey& key) -> QString; auto GPGFRONTEND_CORE_EXPORT GetGpgKeyByGpgAbstractKey(GpgAbstractKey*) -> GpgKey; +/** + * @brief + * + * @param id + * @return true + * @return false + */ +auto GPGFRONTEND_CORE_EXPORT IsKeyGroupID(const KeyId& id) -> bool; } // namespace GpgFrontend \ No newline at end of file diff --git a/src/sdk/GFSDKGpg.cpp b/src/sdk/GFSDKGpg.cpp index 918e4520..8ee1a4d6 100644 --- a/src/sdk/GFSDKGpg.cpp +++ b/src/sdk/GFSDKGpg.cpp @@ -63,11 +63,11 @@ auto GPGFRONTEND_MODULE_SDK_EXPORT GFGpgSignData(int channel, char** key_ids, auto singer_ids = CharArrayToQStringList(key_ids, key_ids_size); - GpgFrontend::KeyArgsList signer_keys; + GpgFrontend::GpgAbstractKeyPtrList signer_keys; for (const auto& signer_id : singer_ids) { auto key = - GpgFrontend::GpgKeyGetter::GetInstance(channel).GetKey(signer_id); - if (key.IsGood()) signer_keys.push_back(key); + GpgFrontend::GpgKeyGetter::GetInstance(channel).GetKeyPtr(signer_id); + if (key != nullptr) signer_keys.push_back(key); } if (signer_keys.empty()) return -1; @@ -103,10 +103,9 @@ auto GPGFRONTEND_MODULE_SDK_EXPORT GFGpgSignData(int channel, char** key_ids, auto GPGFRONTEND_MODULE_SDK_EXPORT GFGpgPublicKey(int channel, char* key_id, int ascii) -> char* { - auto key = GpgFrontend::GpgKeyGetter::GetInstance(channel).GetKey( + auto key = GpgFrontend::GpgKeyGetter::GetInstance(channel).GetKeyPtr( GFUnStrDup(key_id)); - - if (!key.IsGood()) return nullptr; + if (key == nullptr) return nullptr; auto [err, buffer] = GpgFrontend::GpgKeyImportExporter::GetInstance(channel).ExportKey( @@ -151,11 +150,11 @@ GFGpgEncryptData(int channel, char** key_ids, int key_ids_size, char* data, auto encrypt_key_ids = CharArrayToQStringList(key_ids, key_ids_size); - GpgFrontend::KeyArgsList encrypt_keys; + GpgFrontend::GpgAbstractKeyPtrList encrypt_keys; for (const auto& encrypt_key_id : encrypt_key_ids) { - auto key = - GpgFrontend::GpgKeyGetter::GetInstance(channel).GetKey(encrypt_key_id); - if (key.IsGood()) encrypt_keys.push_back(key); + auto key = GpgFrontend::GpgKeyGetter::GetInstance(channel).GetKeyPtr( + encrypt_key_id); + if (key != nullptr) encrypt_keys.push_back(key); } if (encrypt_keys.empty()) return -1; diff --git a/src/test/core/GpgCoreTestBasicOpera.cpp b/src/test/core/GpgCoreTestBasicOpera.cpp index a7bdfead..3e188478 100644 --- a/src/test/core/GpgCoreTestBasicOpera.cpp +++ b/src/test/core/GpgCoreTestBasicOpera.cpp @@ -40,9 +40,9 @@ namespace GpgFrontend::Test { TEST_F(GpgCoreTest, CoreEncryptDecrTest) { - auto encrypt_key = GpgKeyGetter::GetInstance().GetPubkey( + auto encrypt_key = GpgKeyGetter::GetInstance().GetPubkeyPtr( "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); - ASSERT_TRUE(encrypt_key.IsGood()); + ASSERT_TRUE(encrypt_key != nullptr); auto buffer = GFBuffer(QString("Hello GpgFrontend!")); @@ -152,9 +152,9 @@ TEST_F(GpgCoreTest, CoreEncryptDecrTest_KeyNotFound_ResultAnalyse) { } TEST_F(GpgCoreTest, CoreSignVerifyNormalTest) { - auto sign_key = GpgKeyGetter::GetInstance().GetPubkey( + auto sign_key = GpgKeyGetter::GetInstance().GetPubkeyPtr( "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); - ASSERT_TRUE(sign_key.IsGood()); + ASSERT_TRUE(sign_key != nullptr); auto sign_text = GFBuffer(QString("Hello GpgFrontend!")); @@ -179,10 +179,9 @@ TEST_F(GpgCoreTest, CoreSignVerifyNormalTest) { } TEST_F(GpgCoreTest, CoreSignVerifyDetachTest) { - auto sign_key = GpgKeyGetter::GetInstance().GetPubkey( + auto sign_key = GpgKeyGetter::GetInstance().GetPubkeyPtr( "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); - ASSERT_TRUE(sign_key.IsGood()); - + ASSERT_TRUE(sign_key != nullptr); auto sign_text = GFBuffer(QString("Hello GpgFrontend!")); auto [err, data_object] = GpgBasicOperator::GetInstance().SignSync( @@ -206,9 +205,9 @@ TEST_F(GpgCoreTest, CoreSignVerifyDetachTest) { } TEST_F(GpgCoreTest, CoreSignVerifyClearTest) { - auto sign_key = GpgKeyGetter::GetInstance().GetPubkey( + auto sign_key = GpgKeyGetter::GetInstance().GetPubkeyPtr( "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); - ASSERT_TRUE(sign_key.IsGood()); + ASSERT_TRUE(sign_key != nullptr); auto sign_text = GFBuffer(QString("Hello GpgFrontend!")); @@ -232,16 +231,16 @@ TEST_F(GpgCoreTest, CoreSignVerifyClearTest) { } TEST_F(GpgCoreTest, CoreEncryptSignDecrVerifyTest) { - auto encrypt_key = GpgKeyGetter::GetInstance().GetPubkey( + auto encrypt_key = GpgKeyGetter::GetInstance().GetPubkeyPtr( "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); - ASSERT_TRUE(encrypt_key.IsGood()); - auto sign_key = GpgKeyGetter::GetInstance().GetKey( + ASSERT_TRUE(encrypt_key != nullptr); + auto sign_key = GpgKeyGetter::GetInstance().GetKeyPtr( "8933EB283A18995F45D61DAC021D89771B680FFB"); - ASSERT_TRUE(sign_key.IsGood()); + ASSERT_TRUE(sign_key != nullptr); auto encrypt_text = GFBuffer(QString("Hello GpgFrontend!")); - ASSERT_TRUE(sign_key.IsPrivateKey()); - ASSERT_TRUE(sign_key.IsHasActualSignCap()); + ASSERT_TRUE(sign_key->IsPrivateKey()); + ASSERT_TRUE(sign_key->IsHasActualSignCap()); auto [err, data_object] = GpgBasicOperator::GetInstance().EncryptSignSync( {encrypt_key}, {sign_key}, encrypt_text, true); diff --git a/src/test/core/GpgCoreTestFileBasicOpera.cpp b/src/test/core/GpgCoreTestFileBasicOpera.cpp index bb108499..b753636e 100644 --- a/src/test/core/GpgCoreTestFileBasicOpera.cpp +++ b/src/test/core/GpgCoreTestFileBasicOpera.cpp @@ -27,9 +27,9 @@ */ #include "GpgCoreTest.h" -#include "core/GpgModel.h" #include "core/function/gpg/GpgFileOpera.h" #include "core/function/gpg/GpgKeyGetter.h" +#include "core/model/DataObject.h" #include "core/model/GpgDecryptResult.h" #include "core/model/GpgEncryptResult.h" #include "core/model/GpgSignResult.h" @@ -40,9 +40,9 @@ namespace GpgFrontend::Test { TEST_F(GpgCoreTest, CoreFileEncryptDecrTest) { - auto encrypt_key = GpgKeyGetter::GetInstance().GetPubkey( + auto encrypt_key = GpgKeyGetter::GetInstance().GetPubkeyPtr( "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); - ASSERT_TRUE(encrypt_key.IsGood()); + ASSERT_TRUE(encrypt_key != nullptr); auto buffer = GFBuffer(QString("Hello GpgFrontend!")); auto input_file = CreateTempFileAndWriteData(buffer); @@ -72,9 +72,9 @@ TEST_F(GpgCoreTest, CoreFileEncryptDecrTest) { } TEST_F(GpgCoreTest, CoreFileEncryptDecrBinaryTest) { - auto encrypt_key = GpgKeyGetter::GetInstance().GetPubkey( + auto encrypt_key = GpgKeyGetter::GetInstance().GetPubkeyPtr( "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); - ASSERT_TRUE(encrypt_key.IsGood()); + ASSERT_TRUE(encrypt_key != nullptr); auto buffer = GFBuffer(QString("Hello GpgFrontend!")); auto input_file = CreateTempFileAndWriteData(buffer); @@ -165,9 +165,9 @@ TEST_F(GpgCoreTest, CoreFileEncryptSymmetricDecrBinaryTest) { } TEST_F(GpgCoreTest, CoreFileSignVerifyNormalTest) { - auto sign_key = GpgKeyGetter::GetInstance().GetPubkey( + auto sign_key = GpgKeyGetter::GetInstance().GetPubkeyPtr( "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); - ASSERT_TRUE(sign_key.IsGood()); + ASSERT_TRUE(sign_key != nullptr); auto input_file = CreateTempFileAndWriteData("Hello GpgFrontend!"); auto output_file = GetTempFilePath(); @@ -192,9 +192,12 @@ TEST_F(GpgCoreTest, CoreFileSignVerifyNormalTest) { } TEST_F(GpgCoreTest, CoreFileSignVerifyNormalBinaryTest) { - auto sign_key = GpgKeyGetter::GetInstance().GetPubkey( + auto sign_key = GpgKeyGetter::GetInstance().GetKeyPtr( "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); - ASSERT_TRUE(sign_key.IsGood()); + ASSERT_TRUE(sign_key != nullptr); + + ASSERT_TRUE(sign_key->IsPrivateKey()); + ASSERT_TRUE(sign_key->IsHasActualSignCap()); auto input_file = CreateTempFileAndWriteData("Hello GpgFrontend!"); auto output_file = GetTempFilePath(); @@ -219,20 +222,20 @@ TEST_F(GpgCoreTest, CoreFileSignVerifyNormalBinaryTest) { } TEST_F(GpgCoreTest, CoreFileEncryptSignDecrVerifyTest) { - auto encrypt_key = GpgKeyGetter::GetInstance().GetPubkey( + auto encrypt_key = GpgKeyGetter::GetInstance().GetPubkeyPtr( "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); - ASSERT_TRUE(encrypt_key.IsGood()); + ASSERT_TRUE(encrypt_key != nullptr); - auto sign_key = GpgKeyGetter::GetInstance().GetKey( + auto sign_key = GpgKeyGetter::GetInstance().GetKeyPtr( "8933EB283A18995F45D61DAC021D89771B680FFB"); - ASSERT_TRUE(sign_key.IsGood()); + ASSERT_TRUE(sign_key != nullptr); auto buffer = GFBuffer(QString("Hello GpgFrontend!")); auto input_file = CreateTempFileAndWriteData(buffer); auto output_file = GetTempFilePath(); - ASSERT_TRUE(sign_key.IsPrivateKey()); - ASSERT_TRUE(sign_key.IsHasActualSignCap()); + ASSERT_TRUE(sign_key->IsPrivateKey()); + ASSERT_TRUE(sign_key->IsHasActualSignCap()); auto [err, data_object] = GpgFileOpera::GetInstance().EncryptSignFileSync( {encrypt_key}, {sign_key}, input_file, true, output_file); @@ -267,19 +270,19 @@ TEST_F(GpgCoreTest, CoreFileEncryptSignDecrVerifyTest) { } TEST_F(GpgCoreTest, CoreFileEncryptSignDecrVerifyBinaryTest) { - auto encrypt_key = GpgKeyGetter::GetInstance().GetPubkey( + auto encrypt_key = GpgKeyGetter::GetInstance().GetPubkeyPtr( "467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); - ASSERT_TRUE(encrypt_key.IsGood()); - auto sign_key = GpgKeyGetter::GetInstance().GetKey( + ASSERT_TRUE(encrypt_key != nullptr); + auto sign_key = GpgKeyGetter::GetInstance().GetKeyPtr( "8933EB283A18995F45D61DAC021D89771B680FFB"); - ASSERT_TRUE(sign_key.IsGood()); + ASSERT_TRUE(sign_key != nullptr); auto buffer = GFBuffer(QString("Hello GpgFrontend!")); auto input_file = CreateTempFileAndWriteData(buffer); auto output_file = GetTempFilePath(); - ASSERT_TRUE(sign_key.IsPrivateKey()); - ASSERT_TRUE(sign_key.IsHasActualSignCap()); + ASSERT_TRUE(sign_key->IsPrivateKey()); + ASSERT_TRUE(sign_key->IsHasActualSignCap()); auto [err, data_object] = GpgFileOpera::GetInstance().EncryptSignFileSync( {encrypt_key}, {sign_key}, input_file, false, output_file); diff --git a/src/test/core/GpgCoreTestKeyManagement.cpp b/src/test/core/GpgCoreTestKeyManagement.cpp index 6ba24b80..3410e97e 100644 --- a/src/test/core/GpgCoreTestKeyManagement.cpp +++ b/src/test/core/GpgCoreTestKeyManagement.cpp @@ -116,10 +116,10 @@ TEST_F(GpgCoreTest, CoreDeleteSubkeyTestA) { ASSERT_EQ(info->imported, 1); auto key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) - .GetKey("822D7E13F5B85D7D"); - ASSERT_TRUE(key.IsGood()); + .GetKeyPtr("822D7E13F5B85D7D"); + ASSERT_TRUE(key != nullptr); - auto s_key = key.SubKeys(); + auto s_key = key->SubKeys(); ASSERT_EQ(s_key.size(), 5); ASSERT_EQ(s_key[2].ID(), "2D1F9FC59B568A8C"); @@ -130,15 +130,15 @@ TEST_F(GpgCoreTest, CoreDeleteSubkeyTestA) { GpgKeyGetter::GetInstance().FlushKeyCache(); key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) - .GetKey("822D7E13F5B85D7D"); - ASSERT_TRUE(key.IsGood()); + .GetKeyPtr("822D7E13F5B85D7D"); + ASSERT_TRUE(key != nullptr); - s_key = key.SubKeys(); + s_key = key->SubKeys(); ASSERT_EQ(s_key.size(), 4); ASSERT_EQ(s_key[2].ID(), "CE038203C4D03C3D"); - GpgKeyOpera::GetInstance().DeleteKey(key.ID()); + GpgKeyOpera::GetInstance().DeleteKey(key); } TEST_F(GpgCoreTest, CoreSetOwnerTrustA) { @@ -149,59 +149,59 @@ TEST_F(GpgCoreTest, CoreSetOwnerTrustA) { ASSERT_EQ(info->imported, 1); auto key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) - .GetKey("822D7E13F5B85D7D"); - ASSERT_TRUE(key.IsGood()); + .GetKeyPtr("822D7E13F5B85D7D"); + ASSERT_TRUE(key != nullptr); auto res = GpgKeyManager::GetInstance().SetOwnerTrustLevel(key, 1); ASSERT_TRUE(res); GpgKeyGetter::GetInstance().FlushKeyCache(); key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) - .GetKey("822D7E13F5B85D7D"); - ASSERT_TRUE(key.IsGood()); + .GetKeyPtr("822D7E13F5B85D7D"); + ASSERT_TRUE(key != nullptr); // why? - ASSERT_EQ(key.OwnerTrustLevel(), 0); + ASSERT_EQ(key->OwnerTrustLevel(), 0); res = GpgKeyManager::GetInstance().SetOwnerTrustLevel(key, 2); ASSERT_TRUE(res); GpgKeyGetter::GetInstance().FlushKeyCache(); key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) - .GetKey("822D7E13F5B85D7D"); - ASSERT_TRUE(key.IsGood()); + .GetKeyPtr("822D7E13F5B85D7D"); + ASSERT_TRUE(key != nullptr); - ASSERT_EQ(key.OwnerTrustLevel(), 2); + ASSERT_EQ(key->OwnerTrustLevel(), 2); res = GpgKeyManager::GetInstance().SetOwnerTrustLevel(key, 3); ASSERT_TRUE(res); GpgKeyGetter::GetInstance().FlushKeyCache(); key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) - .GetKey("822D7E13F5B85D7D"); - ASSERT_TRUE(key.IsGood()); + .GetKeyPtr("822D7E13F5B85D7D"); + ASSERT_TRUE(key != nullptr); - ASSERT_EQ(key.OwnerTrustLevel(), 3); + ASSERT_EQ(key->OwnerTrustLevel(), 3); res = GpgKeyManager::GetInstance().SetOwnerTrustLevel(key, 4); ASSERT_TRUE(res); GpgKeyGetter::GetInstance().FlushKeyCache(); key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) - .GetKey("822D7E13F5B85D7D"); - ASSERT_TRUE(key.IsGood()); + .GetKeyPtr("822D7E13F5B85D7D"); + ASSERT_TRUE(key != nullptr); - ASSERT_EQ(key.OwnerTrustLevel(), 4); + ASSERT_EQ(key->OwnerTrustLevel(), 4); res = GpgKeyManager::GetInstance().SetOwnerTrustLevel(key, 5); ASSERT_TRUE(res); GpgKeyGetter::GetInstance().FlushKeyCache(); key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) - .GetKey("822D7E13F5B85D7D"); - ASSERT_TRUE(key.IsGood()); + .GetKeyPtr("822D7E13F5B85D7D"); + ASSERT_TRUE(key->IsGood()); - ASSERT_EQ(key.OwnerTrustLevel(), 5); + ASSERT_EQ(key->OwnerTrustLevel(), 5); res = GpgKeyManager::GetInstance().SetOwnerTrustLevel(key, 0); ASSERT_FALSE(res); @@ -212,7 +212,7 @@ TEST_F(GpgCoreTest, CoreSetOwnerTrustA) { res = GpgKeyManager::GetInstance().SetOwnerTrustLevel(key, 6); ASSERT_FALSE(res); - GpgKeyOpera::GetInstance().DeleteKey(key.ID()); + GpgKeyOpera::GetInstance().DeleteKey(key); } TEST_F(GpgCoreTest, CoreRevokeSubkeyTestA) { @@ -223,10 +223,10 @@ TEST_F(GpgCoreTest, CoreRevokeSubkeyTestA) { ASSERT_EQ(info->imported, 1); auto key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) - .GetKey("822D7E13F5B85D7D"); - ASSERT_TRUE(key.IsGood()); + .GetKeyPtr("822D7E13F5B85D7D"); + ASSERT_TRUE(key != nullptr); - auto s_key = key.SubKeys(); + auto s_key = key->SubKeys(); ASSERT_EQ(s_key.size(), 5); ASSERT_EQ(s_key[2].ID(), "2D1F9FC59B568A8C"); @@ -238,17 +238,17 @@ TEST_F(GpgCoreTest, CoreRevokeSubkeyTestA) { GpgKeyGetter::GetInstance().FlushKeyCache(); key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) - .GetKey("822D7E13F5B85D7D"); - ASSERT_TRUE(key.IsGood()); + .GetKeyPtr("822D7E13F5B85D7D"); + ASSERT_TRUE(key != nullptr); - s_key = key.SubKeys(); + s_key = key->SubKeys(); ASSERT_EQ(s_key.size(), 5); ASSERT_EQ(s_key[2].ID(), "2D1F9FC59B568A8C"); ASSERT_TRUE(s_key[2].IsRevoked()); - GpgKeyOpera::GetInstance().DeleteKey(key.ID()); + GpgKeyOpera::GetInstance().DeleteKey(key); } } // namespace GpgFrontend::Test \ No newline at end of file diff --git a/src/test/core/GpgCoreTestKeyOpera.cpp b/src/test/core/GpgCoreTestKeyOpera.cpp index 84aa29f9..ef2d1124 100644 --- a/src/test/core/GpgCoreTestKeyOpera.cpp +++ b/src/test/core/GpgCoreTestKeyOpera.cpp @@ -77,10 +77,10 @@ TEST_F(GpgCoreTest, CoreAddADSKTestA) { ASSERT_EQ(info->imported, 1); auto key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) - .GetKey("5C4D80546EB6E52F"); - ASSERT_TRUE(key.IsGood()); - ASSERT_TRUE(key.IsPrivateKey()); - ASSERT_TRUE(key.IsHasMasterKey()); + .GetKeyPtr("5C4D80546EB6E52F"); + ASSERT_TRUE(key->IsGood()); + ASSERT_TRUE(key->IsPrivateKey()); + ASSERT_TRUE(key->IsHasMasterKey()); auto key_b = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) .GetKey("467F14220CE8DCF780CF4BAD8465C55B25C9B7D1"); @@ -103,16 +103,16 @@ TEST_F(GpgCoreTest, CoreAddADSKTestA) { GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel).FlushKeyCache(); key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) - .GetKey("5C4D80546EB6E52F"); - ASSERT_TRUE(key.IsGood()); - ASSERT_TRUE(key.IsPrivateKey()); - ASSERT_TRUE(key.IsHasMasterKey()); + .GetKeyPtr("5C4D80546EB6E52F"); + ASSERT_TRUE(key->IsGood()); + ASSERT_TRUE(key->IsPrivateKey()); + ASSERT_TRUE(key->IsHasMasterKey()); - auto s_keys = key.SubKeys(); + auto s_keys = key->SubKeys(); ASSERT_EQ(s_keys.size(), 2); ASSERT_EQ(s_keys.last().ID(), "F89C95A05088CC93"); ASSERT_EQ(s_keys.last().IsADSK(), true); - GpgKeyOpera::GetInstance().DeleteKey(key.ID()); + GpgKeyOpera::GetInstance().DeleteKey(key); } }; // namespace GpgFrontend::Test \ No newline at end of file diff --git a/src/test/core/GpgCoreTestKeyUIDOpera.cpp b/src/test/core/GpgCoreTestKeyUIDOpera.cpp index 7b141670..41196d35 100644 --- a/src/test/core/GpgCoreTestKeyUIDOpera.cpp +++ b/src/test/core/GpgCoreTestKeyUIDOpera.cpp @@ -70,10 +70,10 @@ TEST_F(GpgCoreTest, CoreDeleteUIDTestA) { ASSERT_EQ(info->imported, 1); auto key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) - .GetKey("F2D8DFA5F109DE47"); - ASSERT_TRUE(key.IsGood()); + .GetKeyPtr("F2D8DFA5F109DE47"); + ASSERT_TRUE(key->IsGood()); - auto uids = key.UIDs(); + auto uids = key->UIDs(); ASSERT_EQ(uids.size(), 4); ASSERT_EQ(uids[2].GetUID(), "gggggg(ggggg)"); @@ -84,15 +84,15 @@ TEST_F(GpgCoreTest, CoreDeleteUIDTestA) { GpgKeyGetter::GetInstance().FlushKeyCache(); key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) - .GetKey("F2D8DFA5F109DE47"); - ASSERT_TRUE(key.IsGood()); + .GetKeyPtr("F2D8DFA5F109DE47"); + ASSERT_TRUE(key != nullptr); - uids = key.UIDs(); + uids = key->UIDs(); ASSERT_EQ(uids.size(), 3); ASSERT_EQ(uids[2].GetUID(), "hhhhhh(hhhhhhh)"); - GpgKeyOpera::GetInstance().DeleteKey(key.ID()); + GpgKeyOpera::GetInstance().DeleteKey(key); GpgKeyGetter::GetInstance().FlushKeyCache(); } @@ -105,10 +105,10 @@ TEST_F(GpgCoreTest, CoreRevokeUIDTestA) { ASSERT_EQ(info->imported, 1); auto key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) - .GetKey("F2D8DFA5F109DE47"); - ASSERT_TRUE(key.IsGood()); + .GetKeyPtr("F2D8DFA5F109DE47"); + ASSERT_TRUE(key != nullptr); - auto uids = key.UIDs(); + auto uids = key->UIDs(); ASSERT_EQ(uids.size(), 4); ASSERT_EQ(uids[2].GetUID(), "gggggg(ggggg)"); @@ -120,16 +120,16 @@ TEST_F(GpgCoreTest, CoreRevokeUIDTestA) { GpgKeyGetter::GetInstance().FlushKeyCache(); key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) - .GetKey("F2D8DFA5F109DE47"); - ASSERT_TRUE(key.IsGood()); + .GetKeyPtr("F2D8DFA5F109DE47"); + ASSERT_TRUE(key != nullptr); - uids = key.UIDs(); + uids = key->UIDs(); ASSERT_EQ(uids.size(), 4); ASSERT_EQ(uids[2].GetUID(), "gggggg(ggggg)"); ASSERT_TRUE(uids[2].GetRevoked()); - GpgKeyOpera::GetInstance().DeleteKey(key.ID()); + GpgKeyOpera::GetInstance().DeleteKey(key); GpgKeyGetter::GetInstance().FlushKeyCache(); } diff --git a/src/test/core/GpgCoreTestKeygen.cpp b/src/test/core/GpgCoreTestKeygen.cpp index a8ad7005..73f293c7 100644 --- a/src/test/core/GpgCoreTestKeygen.cpp +++ b/src/test/core/GpgCoreTestKeygen.cpp @@ -80,9 +80,10 @@ TEST_F(GpgCoreTest, GenerateKeyRSA2048Test) { auto result = ExtractParams(data_object, 0); ASSERT_TRUE(result.IsGood()); ASSERT_FALSE(result.GetFingerprint().isEmpty()); - auto key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) - .GetKey(result.GetFingerprint()); - ASSERT_TRUE(key.IsGood()); + auto p_key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) + .GetKeyPtr(result.GetFingerprint()); + ASSERT_TRUE(p_key != nullptr); + auto& key = *p_key; ASSERT_EQ(key.Name(), "foo_0"); ASSERT_EQ(key.Email(), "bar@gpgfrontend.bktus.com"); @@ -102,8 +103,7 @@ TEST_F(GpgCoreTest, GenerateKeyRSA2048Test) { ASSERT_TRUE(key.IsHasActualEncrCap()); ASSERT_TRUE(key.IsHasActualSignCap()); - GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) - .DeleteKey(result.GetFingerprint()); + GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel).DeleteKey(p_key); } TEST_F(GpgCoreTest, GenerateKeyRSA4096Test) { @@ -137,12 +137,11 @@ TEST_F(GpgCoreTest, GenerateKeyRSA4096Test) { ASSERT_FALSE(result.GetFingerprint().isEmpty()); auto key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) - .GetKey(result.GetFingerprint()); - ASSERT_TRUE(key.IsGood()); - ASSERT_EQ(key.ExpirationTime().date(), expire_time.date()); + .GetKeyPtr(result.GetFingerprint()); + ASSERT_TRUE(key != nullptr); + ASSERT_EQ(key->ExpirationTime().date(), expire_time.date()); - GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) - .DeleteKey(result.GetFingerprint()); + GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel).DeleteKey(key); } TEST_F(GpgCoreTest, GenerateKeyDSA2048Test) { @@ -174,8 +173,11 @@ TEST_F(GpgCoreTest, GenerateKeyDSA2048Test) { ASSERT_TRUE(result.IsGood()); ASSERT_FALSE(result.GetFingerprint().isEmpty()); - auto key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) - .GetKey(result.GetFingerprint()); + auto p_key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) + .GetKeyPtr(result.GetFingerprint()); + ASSERT_TRUE(p_key != nullptr); + auto& key = *p_key; + ASSERT_TRUE(key.IsGood()); ASSERT_EQ(key.Name(), "foo_1"); ASSERT_EQ(key.Email(), "bar_1@gpgfrontend.bktus.com"); @@ -195,8 +197,7 @@ TEST_F(GpgCoreTest, GenerateKeyDSA2048Test) { ASSERT_FALSE(key.IsHasActualEncrCap()); ASSERT_TRUE(key.IsHasActualSignCap()); - GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) - .DeleteKey(result.GetFingerprint()); + GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel).DeleteKey(p_key); } TEST_F(GpgCoreTest, GenerateKeyED25519Test) { @@ -228,8 +229,11 @@ TEST_F(GpgCoreTest, GenerateKeyED25519Test) { ASSERT_TRUE(result.IsGood()); ASSERT_FALSE(result.GetFingerprint().isEmpty()); - auto key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) - .GetKey(result.GetFingerprint()); + auto p_key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) + .GetKeyPtr(result.GetFingerprint()); + ASSERT_TRUE(p_key != nullptr); + auto& key = *p_key; + ASSERT_TRUE(key.IsGood()); ASSERT_EQ(key.Name(), "foo_4"); ASSERT_EQ(key.Email(), "bar_ed@gpgfrontend.bktus.com"); @@ -249,8 +253,7 @@ TEST_F(GpgCoreTest, GenerateKeyED25519Test) { ASSERT_FALSE(key.IsHasActualEncrCap()); ASSERT_TRUE(key.IsHasActualSignCap()); - GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) - .DeleteKey(result.GetFingerprint()); + GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel).DeleteKey(p_key); } TEST_F(GpgCoreTest, GenerateKeyED25519CV25519Test) { @@ -285,11 +288,12 @@ TEST_F(GpgCoreTest, GenerateKeyED25519CV25519Test) { (data_object->Check())); auto result = ExtractParams(data_object, 0); ASSERT_TRUE(result.IsGood()); - auto fpr = result.GetFingerprint(); - ASSERT_FALSE(fpr.isEmpty()); + ASSERT_FALSE(result.GetFingerprint().isEmpty()); - auto key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel).GetKey(fpr); - ASSERT_TRUE(key.IsGood()); + auto p_key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) + .GetKeyPtr(result.GetFingerprint()); + ASSERT_TRUE(p_key != nullptr); + auto& key = *p_key; ASSERT_EQ(key.Name(), "foo_ec"); ASSERT_EQ(key.Email(), "ec_bar@gpgfrontend.bktus.com"); @@ -325,7 +329,7 @@ TEST_F(GpgCoreTest, GenerateKeyED25519CV25519Test) { ASSERT_TRUE(key.IsHasActualEncrCap()); ASSERT_TRUE(key.IsHasActualSignCap()); - GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel).DeleteKey(fpr); + GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel).DeleteKey(p_key); } TEST_F(GpgCoreTest, GenerateKeyED25519NISTP256Test) { @@ -360,11 +364,12 @@ TEST_F(GpgCoreTest, GenerateKeyED25519NISTP256Test) { (data_object->Check())); auto result = ExtractParams(data_object, 0); ASSERT_TRUE(result.IsGood()); - auto fpr = result.GetFingerprint(); - ASSERT_FALSE(fpr.isEmpty()); + ASSERT_FALSE(result.GetFingerprint().isEmpty()); - auto key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel).GetKey(fpr); - ASSERT_TRUE(key.IsGood()); + auto p_key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) + .GetKeyPtr(result.GetFingerprint()); + ASSERT_TRUE(p_key != nullptr); + auto& key = *p_key; ASSERT_EQ(key.Name(), "foo_ec2"); ASSERT_EQ(key.Email(), "ec2_bar@gpgfrontend.bktus.com"); @@ -400,7 +405,7 @@ TEST_F(GpgCoreTest, GenerateKeyED25519NISTP256Test) { ASSERT_TRUE(key.IsHasActualEncrCap()); ASSERT_TRUE(key.IsHasActualSignCap()); - GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel).DeleteKey(fpr); + GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel).DeleteKey(p_key); } TEST_F(GpgCoreTest, GenerateKeyED25519BRAINPOOLP256R1Test) { @@ -435,11 +440,12 @@ TEST_F(GpgCoreTest, GenerateKeyED25519BRAINPOOLP256R1Test) { (data_object->Check())); auto result = ExtractParams(data_object, 0); ASSERT_TRUE(result.IsGood()); - auto fpr = result.GetFingerprint(); - ASSERT_FALSE(fpr.isEmpty()); + ASSERT_FALSE(result.GetFingerprint().isEmpty()); - auto key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel).GetKey(fpr); - ASSERT_TRUE(key.IsGood()); + auto p_key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) + .GetKeyPtr(result.GetFingerprint()); + ASSERT_TRUE(p_key != nullptr); + auto& key = *p_key; ASSERT_EQ(key.Name(), "foo_ec3"); ASSERT_EQ(key.Email(), "ec3_bar@gpgfrontend.bktus.com"); @@ -475,7 +481,7 @@ TEST_F(GpgCoreTest, GenerateKeyED25519BRAINPOOLP256R1Test) { ASSERT_TRUE(key.IsHasActualEncrCap()); ASSERT_TRUE(key.IsHasActualSignCap()); - GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel).DeleteKey(fpr); + GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel).DeleteKey(p_key); } TEST_F(GpgCoreTest, GenerateKeyNISTP256Test) { @@ -507,9 +513,11 @@ TEST_F(GpgCoreTest, GenerateKeyNISTP256Test) { ASSERT_TRUE(result.IsGood()); ASSERT_FALSE(result.GetFingerprint().isEmpty()); - auto key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) - .GetKey(result.GetFingerprint()); - ASSERT_TRUE(key.IsGood()); + auto p_key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) + .GetKeyPtr(result.GetFingerprint()); + ASSERT_TRUE(p_key != nullptr); + auto& key = *p_key; + ASSERT_EQ(key.Name(), "foo_4"); ASSERT_EQ(key.Email(), "bar_ed@gpgfrontend.bktus.com"); ASSERT_EQ(key.Comment(), "hello gpgfrontend"); @@ -529,8 +537,7 @@ TEST_F(GpgCoreTest, GenerateKeyNISTP256Test) { ASSERT_FALSE(key.IsHasActualEncrCap()); ASSERT_TRUE(key.IsHasActualSignCap()); - GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) - .DeleteKey(result.GetFingerprint()); + GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel).DeleteKey(p_key); } TEST_F(GpgCoreTest, GenerateKeyED448Test) { @@ -562,8 +569,11 @@ TEST_F(GpgCoreTest, GenerateKeyED448Test) { ASSERT_TRUE(result.IsGood()); ASSERT_FALSE(result.GetFingerprint().isEmpty()); - auto key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) - .GetKey(result.GetFingerprint()); + auto p_key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) + .GetKeyPtr(result.GetFingerprint()); + ASSERT_TRUE(p_key != nullptr); + auto& key = *p_key; + ASSERT_TRUE(key.IsGood()); ASSERT_EQ(key.Name(), "foo_4"); ASSERT_EQ(key.Email(), "bar_ed@gpgfrontend.bktus.com"); @@ -584,8 +594,7 @@ TEST_F(GpgCoreTest, GenerateKeyED448Test) { ASSERT_FALSE(key.IsHasActualEncrCap()); ASSERT_TRUE(key.IsHasActualSignCap()); - GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) - .DeleteKey(result.GetFingerprint()); + GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel).DeleteKey(p_key); } TEST_F(GpgCoreTest, GenerateKeySECP256K1Test) { @@ -617,9 +626,11 @@ TEST_F(GpgCoreTest, GenerateKeySECP256K1Test) { ASSERT_TRUE(result.IsGood()); ASSERT_FALSE(result.GetFingerprint().isEmpty()); - auto key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) - .GetKey(result.GetFingerprint()); - ASSERT_TRUE(key.IsGood()); + auto p_key = GpgKeyGetter::GetInstance(kGpgFrontendDefaultChannel) + .GetKeyPtr(result.GetFingerprint()); + ASSERT_TRUE(p_key != nullptr); + auto& key = *p_key; + ASSERT_EQ(key.Name(), "foo_4"); ASSERT_EQ(key.Email(), "bar_ed@gpgfrontend.bktus.com"); ASSERT_EQ(key.Comment(), "hello gpgfrontend"); @@ -639,8 +650,7 @@ TEST_F(GpgCoreTest, GenerateKeySECP256K1Test) { ASSERT_FALSE(key.IsHasActualEncrCap()); ASSERT_TRUE(key.IsHasActualSignCap()); - GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel) - .DeleteKey(result.GetFingerprint()); + GpgKeyOpera::GetInstance(kGpgFrontendDefaultChannel).DeleteKey(p_key); } } // namespace GpgFrontend::Test diff --git a/src/test/core/GpgCoreTestSubkeygen.cpp b/src/test/core/GpgCoreTestSubkeygen.cpp index 09c47903..ad742a1f 100644 --- a/src/test/core/GpgCoreTestSubkeygen.cpp +++ b/src/test/core/GpgCoreTestSubkeygen.cpp @@ -38,9 +38,9 @@ namespace GpgFrontend::Test { TEST_F(GpgCoreTest, GenerateSubkeyRSA2048Test) { - auto p_key = GpgKeyGetter::GetInstance().GetKey( + auto p_key = GpgKeyGetter::GetInstance().GetKeyPtr( "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); - ASSERT_TRUE(p_key.IsGood()); + ASSERT_TRUE(p_key != nullptr); auto s_info = QSharedPointer::create(true); @@ -81,9 +81,9 @@ TEST_F(GpgCoreTest, GenerateSubkeyRSA2048Test) { } TEST_F(GpgCoreTest, GenerateSubkeyDSA2048Test) { - auto p_key = GpgKeyGetter::GetInstance().GetKey( + auto p_key = GpgKeyGetter::GetInstance().GetKeyPtr( "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); - ASSERT_TRUE(p_key.IsGood()); + ASSERT_TRUE(p_key != nullptr); auto s_info = QSharedPointer::create(true); @@ -124,9 +124,9 @@ TEST_F(GpgCoreTest, GenerateSubkeyDSA2048Test) { } TEST_F(GpgCoreTest, GenerateSubkeyELG2048Test) { - auto p_key = GpgKeyGetter::GetInstance().GetKey( + auto p_key = GpgKeyGetter::GetInstance().GetKeyPtr( "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); - ASSERT_TRUE(p_key.IsGood()); + ASSERT_TRUE(p_key != nullptr); auto s_info = QSharedPointer::create(true); @@ -167,9 +167,9 @@ TEST_F(GpgCoreTest, GenerateSubkeyELG2048Test) { } TEST_F(GpgCoreTest, GenerateSubkeyED25519Test) { - auto p_key = GpgKeyGetter::GetInstance().GetKey( + auto p_key = GpgKeyGetter::GetInstance().GetKeyPtr( "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); - ASSERT_TRUE(p_key.IsGood()); + ASSERT_TRUE(p_key != nullptr); auto s_info = QSharedPointer::create(true); @@ -210,9 +210,9 @@ TEST_F(GpgCoreTest, GenerateSubkeyED25519Test) { } TEST_F(GpgCoreTest, GenerateSubkeyCV25519Test) { - auto p_key = GpgKeyGetter::GetInstance().GetKey( + auto p_key = GpgKeyGetter::GetInstance().GetKeyPtr( "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); - ASSERT_TRUE(p_key.IsGood()); + ASSERT_TRUE(p_key != nullptr); auto s_info = QSharedPointer::create(true); @@ -253,9 +253,9 @@ TEST_F(GpgCoreTest, GenerateSubkeyCV25519Test) { } TEST_F(GpgCoreTest, GenerateSubkeyNISTP256Test) { - auto p_key = GpgKeyGetter::GetInstance().GetKey( + auto p_key = GpgKeyGetter::GetInstance().GetKeyPtr( "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); - ASSERT_TRUE(p_key.IsGood()); + ASSERT_TRUE(p_key != nullptr); auto s_info = QSharedPointer::create(true); @@ -295,9 +295,9 @@ TEST_F(GpgCoreTest, GenerateSubkeyNISTP256Test) { } TEST_F(GpgCoreTest, GenerateSubkeyBRAINPOOLP256R1Test) { - auto p_key = GpgKeyGetter::GetInstance().GetKey( + auto p_key = GpgKeyGetter::GetInstance().GetKeyPtr( "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); - ASSERT_TRUE(p_key.IsGood()); + ASSERT_TRUE(p_key != nullptr); auto s_info = QSharedPointer::create(true); @@ -337,9 +337,9 @@ TEST_F(GpgCoreTest, GenerateSubkeyBRAINPOOLP256R1Test) { } TEST_F(GpgCoreTest, GenerateSubkeyX448Test) { - auto p_key = GpgKeyGetter::GetInstance().GetKey( + auto p_key = GpgKeyGetter::GetInstance().GetKeyPtr( "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); - ASSERT_TRUE(p_key.IsGood()); + ASSERT_TRUE(p_key != nullptr); auto s_info = QSharedPointer::create(true); @@ -379,9 +379,9 @@ TEST_F(GpgCoreTest, GenerateSubkeyX448Test) { } TEST_F(GpgCoreTest, GenerateSubkeySECP256K1Test) { - auto p_key = GpgKeyGetter::GetInstance().GetKey( + auto p_key = GpgKeyGetter::GetInstance().GetKeyPtr( "E87C6A2D8D95C818DE93B3AE6A2764F8298DEB29"); - ASSERT_TRUE(p_key.IsGood()); + ASSERT_TRUE(p_key != nullptr); auto s_info = QSharedPointer::create(true); diff --git a/src/ui/GpgFrontendUIInit.cpp b/src/ui/GpgFrontendUIInit.cpp index e9c99dbc..ed9584b9 100644 --- a/src/ui/GpgFrontendUIInit.cpp +++ b/src/ui/GpgFrontendUIInit.cpp @@ -217,7 +217,7 @@ void WaitingAllInitializationFinished() { auto RunGpgFrontendUI(QApplication* app) -> int { // create main window and show it - auto main_window = SecureCreateUniqueObject(); + auto* main_window = new GpgFrontend::UI::MainWindow(); // pre-check, if application need to restart if (CommonUtils::GetInstance()->IsApplicationNeedRestart()) { diff --git a/src/ui/UserInterfaceUtils.cpp b/src/ui/UserInterfaceUtils.cpp index f23eada0..ea5893c1 100644 --- a/src/ui/UserInterfaceUtils.cpp +++ b/src/ui/UserInterfaceUtils.cpp @@ -32,7 +32,7 @@ #include "core/GpgConstants.h" #include "core/function/CoreSignalStation.h" -#include "core/function/gpg/GpgKeyGetter.h" +#include "core/function/gpg/GpgAbstractKeyGetter.h" #include "core/model/CacheObject.h" #include "core/model/GpgImportInformation.h" #include "core/model/SettingsObject.h" @@ -44,12 +44,14 @@ #include "core/utils/BuildInfoUtils.h" #include "core/utils/GpgUtils.h" #include "core/utils/IOUtils.h" -#include "thread/KeyServerImportTask.h" #include "ui/UISignalStation.h" +#include "ui/dialog/KeyGroupManageDialog.h" #include "ui/dialog/WaitingDialog.h" #include "ui/dialog/controller/GnuPGControllerDialog.h" #include "ui/dialog/import_export/KeyServerImportDialog.h" +#include "ui/dialog/keypair_details/KeyDetailsDialog.h" #include "ui/struct/settings_object/KeyServerSO.h" +#include "ui/thread/KeyServerImportTask.h" namespace GpgFrontend::UI { @@ -450,7 +452,7 @@ void CommonUtils::slot_update_key_status() { // flush key cache for all GpgKeyGetter Intances. for (const auto &channel_id : GpgContext::GetAllChannelId()) { LOG_D() << "refreshing key database at channel: " << channel_id; - GpgKeyGetter::GetInstance(channel_id).FlushKeyCache(); + GpgAbstractKeyGetter::GetInstance(channel_id).FlushCache(); } LOG_D() << "refreshing key database at all channel done"; return 0; @@ -509,7 +511,7 @@ auto CommonUtils::KeyExistsInFavoriteList(const QString &key_db_name, } void CommonUtils::AddKey2Favorite(const QString &key_db_name, - const GpgKey &key) { + const GpgAbstractKeyPtr &key) { { auto json_data = CacheObject("all_favorite_key_pairs"); auto cache_obj = AllFavoriteKeyPairsCO(json_data.object()); @@ -519,7 +521,7 @@ void CommonUtils::AddKey2Favorite(const QString &key_db_name, } auto &key_ids = cache_obj.key_dbs[key_db_name].key_ids; - if (!key_ids.contains(key.ID())) key_ids.append(key.ID()); + if (!key_ids.contains(key->ID())) key_ids.append(key->ID()); json_data.setObject(cache_obj.ToJson()); LOG_D() << "current favorite key pairs: " << json_data; @@ -529,7 +531,7 @@ void CommonUtils::AddKey2Favorite(const QString &key_db_name, } void CommonUtils::RemoveKeyFromFavorite(const QString &key_db_name, - const GpgKey &key) { + const GpgAbstractKeyPtr &key) { { auto json_data = CacheObject("all_favorite_key_pairs"); auto cache_obj = AllFavoriteKeyPairsCO(json_data.object()); @@ -538,7 +540,7 @@ void CommonUtils::RemoveKeyFromFavorite(const QString &key_db_name, QMutableListIterator i(cache_obj.key_dbs[key_db_name].key_ids); while (i.hasNext()) { - if (i.next() == key.ID()) i.remove(); + if (i.next() == key->ID()) i.remove(); } json_data.setObject(cache_obj.ToJson()); LOG_D() << "current favorite key pairs: " << json_data; @@ -551,11 +553,16 @@ void CommonUtils::RemoveKeyFromFavorite(const QString &key_db_name, * @brief * */ -void CommonUtils::ImportKeyFromKeyServer(int channel, - const KeyIdArgsList &key_ids) { +void CommonUtils::ImportGpgKeyFromKeyServer(int channel, + const GpgKeyPtrList &keys) { KeyServerSO key_server(SettingsObject("key_server")); auto target_keyserver = key_server.GetTargetServer(); + QStringList key_ids; + for (const auto &key : keys) { + key_ids.push_back(key->ID()); + } + auto *task = new KeyServerImportTask(target_keyserver, channel, key_ids); connect(task, &KeyServerImportTask::SignalKeyServerImportResult, this, &CommonUtils::slot_update_key_from_server_finished); @@ -619,4 +626,26 @@ void CommonUtils::ImportKeyByKeyServerSyncModule(QWidget *parent, int channel, QString("key_%1_import_task").arg(fpr))); } } + +void CommonUtils::OpenDetailsDialogByKey(QWidget *parent, int channel, + const GpgAbstractKeyPtr &key) { + if (key == nullptr) { + QMessageBox::critical(parent, tr("Error"), tr("Key Not Found.")); + return; + } + + switch (key->KeyType()) { + case GpgAbstractKeyType::kGPG_KEY: + new KeyDetailsDialog(channel, qSharedPointerDynamicCast(key), + parent); + break; + case GpgAbstractKeyType::kGPG_KEYGROUP: + new KeyGroupManageDialog( + channel, qSharedPointerDynamicCast(key), parent); + case GpgAbstractKeyType::kNONE: + case GpgAbstractKeyType::kGPG_SUBKEY: + break; + } +} + } // namespace GpgFrontend::UI \ No newline at end of file diff --git a/src/ui/UserInterfaceUtils.h b/src/ui/UserInterfaceUtils.h index 372bc55a..9f79cec2 100644 --- a/src/ui/UserInterfaceUtils.h +++ b/src/ui/UserInterfaceUtils.h @@ -62,7 +62,6 @@ void show_verify_details(QWidget* parent, InfoBoardWidget* info_board, */ void ImportUnknownKeyFromKeyserver(QWidget* parent, const GpgVerifyResultAnalyse& verify_res); - /** * @brief * @@ -133,19 +132,30 @@ class CommonUtils : public QWidget { * @brief * */ - void AddKey2Favorite(const QString& key_db_name, const GpgKey& key); + void AddKey2Favorite(const QString& key_db_name, + const GpgAbstractKeyPtr& key); /** * @brief * */ - void RemoveKeyFromFavorite(const QString& key_db_name, const GpgKey& key); + void RemoveKeyFromFavorite(const QString& key_db_name, + const GpgAbstractKeyPtr& key); /** * @brief * */ - void ImportKeyFromKeyServer(int channel, const KeyIdArgsList&); + void ImportGpgKeyFromKeyServer(int channel, const GpgKeyPtrList&); + + /** + * @brief + * + * @param parent + * @param key + */ + static void OpenDetailsDialogByKey(QWidget* parent, int channel, + const GpgAbstractKeyPtr& key); signals: /** diff --git a/src/ui/dialog/ADSKsPicker.cpp b/src/ui/dialog/ADSKsPicker.cpp index f10a936a..a8afb9bf 100644 --- a/src/ui/dialog/ADSKsPicker.cpp +++ b/src/ui/dialog/ADSKsPicker.cpp @@ -38,9 +38,14 @@ ADSKsPicker::ADSKsPicker(int channel, QWidget* parent) : GeneralDialog(typeid(ADSKsPicker).name(), parent), tree_view_(new KeyTreeView( - channel, [](GpgAbstractKey* k) { return k->IsSubKey(); }, + channel, + [](GpgAbstractKey* k) { + return k->KeyType() == GpgAbstractKeyType::kGPG_SUBKEY; + }, [=](const GpgAbstractKey* k) { - return (!k->IsSubKey() || (k->IsSubKey() && k->IsHasEncrCap())) && + return (k->KeyType() != GpgAbstractKeyType::kGPG_SUBKEY || + (k->KeyType() == GpgAbstractKeyType::kGPG_SUBKEY && + k->IsHasEncrCap())) && filter(k); })) { auto* confirm_button = new QPushButton(tr("Confirm")); diff --git a/src/ui/dialog/KeyGroupCreationDialog.cpp b/src/ui/dialog/KeyGroupCreationDialog.cpp new file mode 100644 index 00000000..506c173d --- /dev/null +++ b/src/ui/dialog/KeyGroupCreationDialog.cpp @@ -0,0 +1,119 @@ +/** + * Copyright (C) 2021-2024 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend 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 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend 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 GpgFrontend. If not, see . + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "KeyGroupCreationDialog.h" + +#include "core/function/gpg/GpgKeyGroupGetter.h" +#include "core/model/GpgKeyGroup.h" +#include "ui/UISignalStation.h" + +namespace GpgFrontend::UI { +KeyGroupCreationDialog::KeyGroupCreationDialog(int channel, QStringList key_ids, + QWidget* parent) + : GeneralDialog(typeid(KeyGroupCreationDialog).name(), parent), + current_gpg_context_channel_(channel), + key_ids_(key_ids) { + assert(!key_ids.isEmpty()); + + name_ = new QLineEdit(); + name_->setMinimumWidth(240); + email_ = new QLineEdit(); + email_->setMinimumWidth(240); + comment_ = new QLineEdit(); + comment_->setMinimumWidth(240); + create_button_ = new QPushButton("Create"); + error_label_ = new QLabel(); + + auto* grid_layout = new QGridLayout(); + grid_layout->addWidget(new QLabel(tr("Name")), 0, 0); + grid_layout->addWidget(new QLabel(tr("Email")), 1, 0); + grid_layout->addWidget(new QLabel(tr("Comment")), 2, 0); + + grid_layout->addWidget(name_, 0, 1); + grid_layout->addWidget(email_, 1, 1); + grid_layout->addWidget(comment_, 2, 1); + + grid_layout->addWidget(create_button_, 3, 0, 1, 2); + grid_layout->addWidget(error_label_, 4, 0, 1, 2); + + connect(create_button_, &QPushButton::clicked, this, + &KeyGroupCreationDialog::slot_create_new_uid); + + connect(this, &KeyGroupCreationDialog::SignalCreated, + UISignalStation::GetInstance(), + &UISignalStation::SignalKeyDatabaseRefresh); + + this->setLayout(grid_layout); + this->setWindowTitle(tr("Create New Key Group")); + this->setAttribute(Qt::WA_DeleteOnClose, true); + this->setModal(true); +} + +void KeyGroupCreationDialog::slot_create_new_uid() { + QString buffer; + QTextStream error_stream(&buffer); + + /** + * check for errors in keygen dialog input + */ + if ((name_->text()).size() < 5) { + error_stream << " " << tr("Name must contain at least five characters.") + << Qt::endl; + } + if (email_->text().isEmpty() || !check_email_address(email_->text())) { + error_stream << " " << tr("Please give a email address.") << Qt::endl; + } + auto error_string = error_stream.readAll(); + if (error_string.isEmpty()) { + auto p_kg = + GpgKeyGroup{name_->text(), email_->text(), comment_->text(), key_ids_}; + GpgKeyGroupGetter::GetInstance(current_gpg_context_channel_) + .AddKeyGroup(p_kg); + + emit SignalCreated(); + this->close(); + } else { + /** + * create error message + */ + error_label_->setAutoFillBackground(true); + QPalette error = error_label_->palette(); + error.setColor(QPalette::Window, "#ff8080"); + error_label_->setPalette(error); + error_label_->setText(error_string); + + this->show(); + this->raise(); + this->activateWindow(); + } +} + +auto KeyGroupCreationDialog::check_email_address(const QString& str) -> bool { + return re_email_.match(str).hasMatch(); +} +} // namespace GpgFrontend::UI diff --git a/src/ui/dialog/KeyGroupCreationDialog.h b/src/ui/dialog/KeyGroupCreationDialog.h new file mode 100644 index 00000000..634c9148 --- /dev/null +++ b/src/ui/dialog/KeyGroupCreationDialog.h @@ -0,0 +1,90 @@ +/** + * Copyright (C) 2021-2024 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend 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 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend 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 GpgFrontend. If not, see . + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#pragma once + +#include "core/function/gpg/GpgContext.h" +#include "core/model/GpgKey.h" +#include "core/typedef/GpgTypedef.h" +#include "ui/dialog/GeneralDialog.h" + +namespace GpgFrontend::UI { +class KeyGroupCreationDialog : public GeneralDialog { + Q_OBJECT + + public: + /** + * @brief Construct a new Key New U I D Dialog object + * + * @param key + * @param parent + */ + KeyGroupCreationDialog(int channel, QStringList key_ids, + QWidget* parent = nullptr); + + signals: + /** + * @brief + * + */ + void SignalCreated(); + + private slots: + + /** + * @brief + * + */ + void slot_create_new_uid(); + + private: + int current_gpg_context_channel_; + QStringList key_ids_; ///< + + QLineEdit* name_{}; ///< + QLineEdit* email_{}; ///< + QLineEdit* comment_{}; ///< + + QPushButton* create_button_{}; ///< + + QStringList error_messages_; ///< + QLabel* error_label_{}; ///< + + QRegularExpression re_email_{ + R"((?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\]))"}; + + /** + * @brief + * + * @param str + * @return true + * @return false + */ + auto check_email_address(const QString& str) -> bool; +}; +} // namespace GpgFrontend::UI diff --git a/src/ui/dialog/KeyGroupManageDialog.cpp b/src/ui/dialog/KeyGroupManageDialog.cpp new file mode 100644 index 00000000..1a994585 --- /dev/null +++ b/src/ui/dialog/KeyGroupManageDialog.cpp @@ -0,0 +1,163 @@ +/** + * Copyright (C) 2021-2024 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend 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 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend 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 GpgFrontend. If not, see . + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "KeyGroupManageDialog.h" + +#include "core/function/gpg/GpgAbstractKeyGetter.h" +#include "ui/widgets/KeyList.h" + +// +#include "ui_KeyGroupManageDialog.h" + +namespace GpgFrontend::UI { + +KeyGroupManageDialog::KeyGroupManageDialog( + int channel, const QSharedPointer& key_group, QWidget* parent) + : GeneralDialog(typeid(KeyGroupManageDialog).name(), parent), + ui_(QSharedPointer::create()), + channel_(channel), + key_group_(key_group) { + ui_->setupUi(this); + + connect(ui_->addButton, &QPushButton::clicked, this, + &KeyGroupManageDialog::slot_add_to_key_group); + + connect(ui_->removeButton, &QPushButton::clicked, this, + &KeyGroupManageDialog::slot_remove_from_key_group); + + ui_->keyGroupKeyList->Init( + channel, KeyMenuAbility::kCOLUMN_FILTER | KeyMenuAbility::kSEARCH_BAR, + GpgKeyTableColumn::kTYPE | GpgKeyTableColumn::kNAME | + GpgKeyTableColumn::kEMAIL_ADDRESS | GpgKeyTableColumn::kKEY_ID); + ui_->keyGroupKeyList->AddListGroupTab( + tr("Key Group"), "key-group", + GpgKeyTableDisplayMode::kPRIVATE_KEY | + GpgKeyTableDisplayMode::kPUBLIC_KEY, + [=](const GpgAbstractKey* key) -> bool { + return key_group_->KeyIds().contains(key->ID()); + }); + ui_->keyGroupKeyList->SlotRefresh(); + + ui_->keyList->Init( + channel, KeyMenuAbility::kCOLUMN_FILTER | KeyMenuAbility::kSEARCH_BAR, + GpgKeyTableColumn::kTYPE | GpgKeyTableColumn::kNAME | + GpgKeyTableColumn::kEMAIL_ADDRESS | GpgKeyTableColumn::kKEY_ID); + ui_->keyList->AddListGroupTab( + tr("Default"), "default", + GpgKeyTableDisplayMode::kPRIVATE_KEY | + GpgKeyTableDisplayMode::kPUBLIC_KEY, + [=](const GpgAbstractKey* key) -> bool { + return key->IsHasEncrCap() && key->ID() != key_group_->ID() && + !key_group_->KeyIds().contains(key->ID()); + }); + ui_->keyList->SlotRefresh(); + + QTimer::singleShot(200, [=]() { slot_notify_invalid_key_ids(); }); + + this->setModal(true); + this->setWindowTitle(tr("Key Group Management")); + + movePosition2CenterOfParent(); + + this->show(); + this->raise(); + this->activateWindow(); +} + +void KeyGroupManageDialog::slot_add_to_key_group() { + auto keys = ui_->keyList->GetCheckedKeys(); + QSet set; + + GpgAbstractKeyPtrList failed_keys; + auto& getter = GpgKeyGroupGetter::GetInstance(channel_); + for (const auto& key : keys) { + if (!getter.AddKey2KeyGroup(key_group_->ID(), key)) { + failed_keys.push_back(key); + } + } + + ui_->keyGroupKeyList->RefreshKeyTable(0); + ui_->keyList->RefreshKeyTable(0); + + if (!failed_keys.isEmpty()) { + QStringList failed_ids; + for (const auto& key : failed_keys) { + failed_ids << key->ID(); + } + + QMessageBox::warning(this, tr("Some Keys Failed"), + tr("Some keys could not be added to the group:\n%1") + .arg(failed_ids.join(", "))); + } +} + +void KeyGroupManageDialog::slot_remove_from_key_group() { + auto keys = ui_->keyGroupKeyList->GetCheckedKeys(); + + auto& getter = GpgKeyGroupGetter::GetInstance(channel_); + for (const auto& key : keys) { + getter.RemoveKeyFromKeyGroup(key_group_->ID(), key->ID()); + } + + ui_->keyGroupKeyList->RefreshKeyTable(0); + ui_->keyList->RefreshKeyTable(0); +} + +void KeyGroupManageDialog::slot_notify_invalid_key_ids() { + auto key_ids = key_group_->KeyIds(); + + QStringList invalid_key_ids; + for (const auto& key_id : key_ids) { + auto key = GpgAbstractKeyGetter::GetInstance(channel_).GetKey(key_id); + if (key == nullptr) invalid_key_ids.push_back(key_id); + } + + if (invalid_key_ids.isEmpty()) { + return; + } + + const QString id_list = invalid_key_ids.join(", "); + const auto message = + tr("This Key Group contains some invalid keys:\n\n%1\n\n" + "These keys are no longer available. Do you want to remove them from " + "the group?") + .arg(id_list); + + const auto reply = QMessageBox::question( + this, tr("Invalid Keys in Group"), message, + QMessageBox::Yes | QMessageBox::No, QMessageBox::No); + + if (reply == QMessageBox::Yes) { + auto key_ids = key_group_->KeyIds(); + auto& getter = GpgKeyGroupGetter::GetInstance(channel_); + for (const auto& key_id : invalid_key_ids) { + getter.RemoveKeyFromKeyGroup(key_group_->ID(), key_id); + } + } +} +} // namespace GpgFrontend::UI diff --git a/src/ui/dialog/KeyGroupManageDialog.h b/src/ui/dialog/KeyGroupManageDialog.h new file mode 100644 index 00000000..66211d28 --- /dev/null +++ b/src/ui/dialog/KeyGroupManageDialog.h @@ -0,0 +1,83 @@ +/** + * Copyright (C) 2021-2024 Saturneric + * + * This file is part of GpgFrontend. + * + * GpgFrontend 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 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend 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 GpgFrontend. If not, see . + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#pragma once + +#include "core/model/GpgKeyGroup.h" +#include "ui/dialog//GeneralDialog.h" + +class Ui_KeyGroupManageDialog; + +namespace GpgFrontend::UI { + +class KeyList; + +/** + * @brief + * + */ +class KeyGroupManageDialog : public GeneralDialog { + Q_OBJECT + + public: + /** + * @brief Construct a new Signers Picker object + * + * @param parent + */ + explicit KeyGroupManageDialog(int channel, + const QSharedPointer& key_group, + QWidget* parent = nullptr); + + private slots: + + /** + * @brief + * + */ + void slot_add_to_key_group(); + + /** + * @brief + * + */ + void slot_remove_from_key_group(); + + /** + * @brief + * + */ + void slot_notify_invalid_key_ids(); + + private: + QSharedPointer ui_; ///< + int channel_; + QSharedPointer key_group_; +}; + +} // namespace GpgFrontend::UI diff --git a/src/ui/dialog/SignersPicker.cpp b/src/ui/dialog/SignersPicker.cpp index fa72287e..94a8f8df 100644 --- a/src/ui/dialog/SignersPicker.cpp +++ b/src/ui/dialog/SignersPicker.cpp @@ -51,7 +51,7 @@ SignersPicker::SignersPicker(int channel, QWidget* parent) this); key_list_->AddListGroupTab( tr("Signers"), "signers", GpgKeyTableDisplayMode::kPRIVATE_KEY, - [](const GpgKey& key) -> bool { return key.IsHasActualSignCap(); }); + [](const GpgAbstractKey* key) -> bool { return key->IsHasSignCap(); }); key_list_->SlotRefresh(); auto* vbox2 = new QVBoxLayout(); @@ -79,20 +79,10 @@ SignersPicker::SignersPicker(int channel, QWidget* parent) this->activateWindow(); } -auto SignersPicker::GetCheckedSigners() -> GpgFrontend::KeyIdArgsList { +auto SignersPicker::GetCheckedSigners() -> GpgAbstractKeyPtrList { return key_list_->GetCheckedPrivateKey(); } -auto SignersPicker::GetCheckedSignerKeyIds() -> GpgFrontend::KeyIdArgsList { - auto priv_keys = key_list_->GetCheckedPrivateKey(); - - QStringList r; - for (const auto& priv_key : priv_keys) { - r.append(priv_key); - } - return r; -} - auto SignersPicker::GetStatus() const -> bool { return this->accepted_; } } // namespace GpgFrontend::UI diff --git a/src/ui/dialog/SignersPicker.h b/src/ui/dialog/SignersPicker.h index 826ccfab..25f3d440 100644 --- a/src/ui/dialog/SignersPicker.h +++ b/src/ui/dialog/SignersPicker.h @@ -56,14 +56,8 @@ class SignersPicker : public GeneralDialog { * * @return GpgFrontend::KeyIdArgsListPtr */ - auto GetCheckedSigners() -> KeyIdArgsList; + auto GetCheckedSigners() -> GpgAbstractKeyPtrList; - /** - * @brief Get the Checked Signer Key Ids object - * - * @return QStringList - */ - auto GetCheckedSignerKeyIds() -> KeyIdArgsList; /** * * @return diff --git a/src/ui/dialog/controller/SmartCardControllerDialog.h b/src/ui/dialog/controller/SmartCardControllerDialog.h index 83a717ee..affe01a8 100644 --- a/src/ui/dialog/controller/SmartCardControllerDialog.h +++ b/src/ui/dialog/controller/SmartCardControllerDialog.h @@ -29,7 +29,6 @@ #pragma once #include "core/model/GpgOpenPGPCard.h" -#include "core/typedef/CoreTypedef.h" #include "ui/dialog/GeneralDialog.h" class Ui_SmartCardControllerDialog; diff --git a/src/ui/dialog/import_export/ExportKeyPackageDialog.cpp b/src/ui/dialog/import_export/ExportKeyPackageDialog.cpp index 7aab31b5..325eba98 100644 --- a/src/ui/dialog/import_export/ExportKeyPackageDialog.cpp +++ b/src/ui/dialog/import_export/ExportKeyPackageDialog.cpp @@ -28,18 +28,16 @@ #include "ExportKeyPackageDialog.h" -#include "core/GpgModel.h" #include "core/function/KeyPackageOperator.h" -#include "core/function/gpg/GpgKeyGetter.h" #include "ui/function/GpgOperaHelper.h" #include "ui_ExportKeyPackageDialog.h" GpgFrontend::UI::ExportKeyPackageDialog::ExportKeyPackageDialog( - int channel, KeyIdArgsList key_ids, QWidget* parent) + int channel, GpgAbstractKeyPtrList keys, QWidget* parent) : GeneralDialog(typeid(ExportKeyPackageDialog).name(), parent), ui_(GpgFrontend::SecureCreateSharedObject()), current_gpg_context_channel_(channel), - key_ids_(std::move(key_ids)) { + keys_(std::move(keys)) { ui_->setupUi(this); ui_->nameValueLabel->setText(KeyPackageOperator::GenerateKeyPackageName()); @@ -95,29 +93,23 @@ GpgFrontend::UI::ExportKeyPackageDialog::ExportKeyPackageDialog( return; } - // get suitable key ids - auto keys = GpgKeyGetter::GetInstance(current_gpg_context_channel_) - .GetKeys(key_ids_); - assert(std::all_of(keys.begin(), keys.end(), - [](const auto& key) { return key.IsGood(); })); - - auto keys_new_end = - std::remove_if(keys.begin(), keys.end(), [this](const auto& key) { - return ui_->noPublicKeyCheckBox->isChecked() && !key.IsPrivateKey(); + auto it = + std::remove_if(keys_.begin(), keys_.end(), [this](const auto& key) { + return ui_->noPublicKeyCheckBox->isChecked() && !key->IsPrivateKey(); }); - keys.erase(keys_new_end, keys.end()); + keys_.erase(it, keys_.end()); - if (keys.empty()) { + if (keys_.empty()) { QMessageBox::critical(this, tr("Error"), tr("No key is suitable to export.")); return; } GpgOperaHelper::WaitForOpera( - this, tr("Generating"), [this, keys](const OperaWaitingHd& op_hd) { + this, tr("Generating"), [this](const OperaWaitingHd& op_hd) { KeyPackageOperator::GenerateKeyPackage( ui_->outputPathLabel->text(), ui_->nameValueLabel->text(), - current_gpg_context_channel_, keys, passphrase_, + current_gpg_context_channel_, keys_, passphrase_, ui_->includeSecretKeyCheckBox->isChecked(), [=](GFError err, const DataObjectPtr&) { // stop waiting diff --git a/src/ui/dialog/import_export/ExportKeyPackageDialog.h b/src/ui/dialog/import_export/ExportKeyPackageDialog.h index 07722a21..f457e405 100644 --- a/src/ui/dialog/import_export/ExportKeyPackageDialog.h +++ b/src/ui/dialog/import_export/ExportKeyPackageDialog.h @@ -50,13 +50,13 @@ class ExportKeyPackageDialog : public GeneralDialog { * @param key_ids * @param parent */ - explicit ExportKeyPackageDialog(int channel, KeyIdArgsList key_ids, + explicit ExportKeyPackageDialog(int channel, GpgAbstractKeyPtrList keys, QWidget* parent); private: std::shared_ptr ui_; ///< int current_gpg_context_channel_; - KeyIdArgsList key_ids_; ///< - QString passphrase_; ///< + GpgAbstractKeyPtrList keys_; ///< + QString passphrase_; ///< }; } // namespace GpgFrontend::UI diff --git a/src/ui/dialog/import_export/KeyImportDetailDialog.cpp b/src/ui/dialog/import_export/KeyImportDetailDialog.cpp index 34a050ce..24062796 100644 --- a/src/ui/dialog/import_export/KeyImportDetailDialog.cpp +++ b/src/ui/dialog/import_export/KeyImportDetailDialog.cpp @@ -28,7 +28,6 @@ #include "KeyImportDetailDialog.h" -#include "core/GpgModel.h" #include "core/function/gpg/GpgKeyGetter.h" #include "core/model/GpgImportInformation.h" diff --git a/src/ui/dialog/import_export/KeyUploadDialog.cpp b/src/ui/dialog/import_export/KeyUploadDialog.cpp index efa72802..346be765 100644 --- a/src/ui/dialog/import_export/KeyUploadDialog.cpp +++ b/src/ui/dialog/import_export/KeyUploadDialog.cpp @@ -29,9 +29,8 @@ #include "KeyUploadDialog.h" #include +#include -#include "core/GpgModel.h" -#include "core/function/gpg/GpgKeyGetter.h" #include "core/function/gpg/GpgKeyImportExporter.h" #include "core/model/SettingsObject.h" #include "core/utils/BuildInfoUtils.h" @@ -41,14 +40,13 @@ namespace GpgFrontend::UI { -KeyUploadDialog::KeyUploadDialog(int channel, const KeyIdArgsList& keys_ids, +KeyUploadDialog::KeyUploadDialog(int channel, GpgAbstractKeyPtrList keys, QWidget* parent) : GeneralDialog(typeid(KeyUploadDialog).name(), parent), current_gpg_context_channel_(channel), - m_keys_(GpgKeyGetter::GetInstance(current_gpg_context_channel_) - .GetKeys(keys_ids)) { - assert(std::all_of(m_keys_.begin(), m_keys_.end(), - [](const auto& key) { return key.IsGood(); })); + keys_(std::move(keys)) { + assert(std::all_of(keys_.begin(), keys_.end(), + [](const auto& key) { return key->IsGood(); })); auto* pb = new QProgressBar(); pb->setRange(0, 0); @@ -70,7 +68,7 @@ KeyUploadDialog::KeyUploadDialog(int channel, const KeyIdArgsList& keys_ids, void KeyUploadDialog::SlotUpload() { GpgKeyImportExporter::GetInstance(current_gpg_context_channel_) - .ExportKeys(m_keys_, false, true, false, false, + .ExportKeys(keys_, false, true, false, false, [=](GpgError err, const DataObjectPtr& data_obj) { if (CheckGpgError(err) != GPG_ERR_NO_ERROR) { CommonUtils::RaiseMessageBox(this, err); diff --git a/src/ui/dialog/import_export/KeyUploadDialog.h b/src/ui/dialog/import_export/KeyUploadDialog.h index 36616037..8d3be02f 100644 --- a/src/ui/dialog/import_export/KeyUploadDialog.h +++ b/src/ui/dialog/import_export/KeyUploadDialog.h @@ -48,7 +48,7 @@ class KeyUploadDialog : public GeneralDialog { * @param keys_ids * @param parent */ - explicit KeyUploadDialog(int channel, const KeyIdArgsList& keys_ids, + explicit KeyUploadDialog(int channel, GpgAbstractKeyPtrList keys, QWidget* parent); public slots: @@ -76,8 +76,8 @@ class KeyUploadDialog : public GeneralDialog { private: int current_gpg_context_channel_; - GpgKeyList m_keys_; ///< - QByteArray m_key_data_; ///< + GpgAbstractKeyPtrList keys_; ///< + QByteArray m_key_data_; ///< }; } // namespace GpgFrontend::UI diff --git a/src/ui/dialog/key_generate/SubkeyGenerateDialog.cpp b/src/ui/dialog/key_generate/SubkeyGenerateDialog.cpp index 58734c7d..662ac77a 100644 --- a/src/ui/dialog/key_generate/SubkeyGenerateDialog.cpp +++ b/src/ui/dialog/key_generate/SubkeyGenerateDialog.cpp @@ -30,8 +30,8 @@ #include #include +#include -#include "core/function/gpg/GpgKeyGetter.h" #include "core/function/gpg/GpgKeyOpera.h" #include "core/utils/GpgUtils.h" #include "ui/UISignalStation.h" @@ -44,17 +44,16 @@ namespace GpgFrontend::UI { -SubkeyGenerateDialog::SubkeyGenerateDialog(int channel, const KeyId& key_id, +SubkeyGenerateDialog::SubkeyGenerateDialog(int channel, GpgKeyPtr key, QWidget* parent) : GeneralDialog(typeid(SubkeyGenerateDialog).name(), parent), ui_(QSharedPointer::create()), current_gpg_context_channel_(channel), - key_(GpgKeyGetter::GetInstance(current_gpg_context_channel_) - .GetKey(key_id)), + key_(std::move(key)), gen_subkey_info_(QSharedPointer::create(true)), supported_subkey_algos_(KeyGenerateInfo::GetSupportedSubkeyAlgo()) { ui_->setupUi(this); - assert(key_.IsGood()); + assert(key_ != nullptr); ui_->algoLabel->setText(tr("Algorithm")); ui_->keyLengthLabel->setText(tr("Key Length")); diff --git a/src/ui/dialog/key_generate/SubkeyGenerateDialog.h b/src/ui/dialog/key_generate/SubkeyGenerateDialog.h index 96dee49e..683c3b66 100644 --- a/src/ui/dialog/key_generate/SubkeyGenerateDialog.h +++ b/src/ui/dialog/key_generate/SubkeyGenerateDialog.h @@ -53,8 +53,7 @@ class SubkeyGenerateDialog : public GeneralDialog { * @param key_id * @param parent */ - explicit SubkeyGenerateDialog(int channel, const KeyId& key_id, - QWidget* parent); + explicit SubkeyGenerateDialog(int channel, GpgKeyPtr key, QWidget* parent); private slots: @@ -68,7 +67,7 @@ class SubkeyGenerateDialog : public GeneralDialog { QSharedPointer ui_; ///< int current_gpg_context_channel_; ///< - GpgKey key_; ///< + GpgKeyPtr key_; ///< QSharedPointer gen_subkey_info_; ///< QContainer supported_subkey_algos_; ///< diff --git a/src/ui/dialog/keypair_details/KeyDetailsDialog.cpp b/src/ui/dialog/keypair_details/KeyDetailsDialog.cpp index b3cb3a9d..273d3316 100644 --- a/src/ui/dialog/keypair_details/KeyDetailsDialog.cpp +++ b/src/ui/dialog/keypair_details/KeyDetailsDialog.cpp @@ -36,29 +36,28 @@ #include "ui/dialog/keypair_details/KeyPairUIDTab.h" namespace GpgFrontend::UI { -KeyDetailsDialog::KeyDetailsDialog(int channel, const GpgKey& key, +KeyDetailsDialog::KeyDetailsDialog(int channel, const GpgKeyPtr& key, QWidget* parent) : GeneralDialog(typeid(KeyDetailsDialog).name(), parent), current_gpg_context_channel_(channel) { tab_widget_ = new QTabWidget(); tab_widget_->addTab( - new KeyPairDetailTab(current_gpg_context_channel_, key.ID(), tab_widget_), + new KeyPairDetailTab(current_gpg_context_channel_, key, tab_widget_), tr("KeyPair")); - if (!key.IsRevoked()) { + if (!key->IsRevoked()) { tab_widget_->addTab( - new KeyPairUIDTab(current_gpg_context_channel_, key.ID(), tab_widget_), + new KeyPairUIDTab(current_gpg_context_channel_, key, tab_widget_), tr("UIDs")); - - tab_widget_->addTab(new KeyPairSubkeyTab(current_gpg_context_channel_, - key.ID(), tab_widget_), - tr("Keychain")); - tab_widget_->addTab(new KeyPairOperaTab(current_gpg_context_channel_, - key.ID(), tab_widget_), - tr("Operations")); + tab_widget_->addTab( + new KeyPairSubkeyTab(current_gpg_context_channel_, key, tab_widget_), + tr("Keychain")); + tab_widget_->addTab( + new KeyPairOperaTab(current_gpg_context_channel_, key, tab_widget_), + tr("Operations")); } - QString m_key_id = key.ID(); + QString m_key_id = key->ID(); connect(UISignalStation::GetInstance(), &UISignalStation::SignalKeyRevoked, this, [this, m_key_id](const QString& key_id) { if (key_id == m_key_id) this->close(); diff --git a/src/ui/dialog/keypair_details/KeyDetailsDialog.h b/src/ui/dialog/keypair_details/KeyDetailsDialog.h index 2c7121d1..35694a27 100644 --- a/src/ui/dialog/keypair_details/KeyDetailsDialog.h +++ b/src/ui/dialog/keypair_details/KeyDetailsDialog.h @@ -39,7 +39,7 @@ class KeyDetailsDialog : public GeneralDialog { Q_OBJECT public: - explicit KeyDetailsDialog(int channel, const GpgKey& key, + explicit KeyDetailsDialog(int channel, const GpgKeyPtr& key, QWidget* parent = nullptr); private: diff --git a/src/ui/dialog/keypair_details/KeyNewUIDDialog.cpp b/src/ui/dialog/keypair_details/KeyNewUIDDialog.cpp index 754999a2..d641c4d3 100644 --- a/src/ui/dialog/keypair_details/KeyNewUIDDialog.cpp +++ b/src/ui/dialog/keypair_details/KeyNewUIDDialog.cpp @@ -28,19 +28,17 @@ #include "KeyNewUIDDialog.h" -#include "core/GpgModel.h" -#include "core/function/gpg/GpgKeyGetter.h" +#include + #include "core/function/gpg/GpgUIDOperator.h" #include "ui/UISignalStation.h" namespace GpgFrontend::UI { -KeyNewUIDDialog::KeyNewUIDDialog(int channel, const KeyId& key_id, - QWidget* parent) +KeyNewUIDDialog::KeyNewUIDDialog(int channel, GpgKeyPtr key, QWidget* parent) : GeneralDialog(typeid(KeyNewUIDDialog).name(), parent), current_gpg_context_channel_(channel), - m_key_(GpgKeyGetter::GetInstance(current_gpg_context_channel_) - .GetKey(key_id)) { - assert(m_key_.IsGood()); + m_key_(std::move(key)) { + assert(m_key_ != nullptr); name_ = new QLineEdit(); name_->setMinimumWidth(240); @@ -51,7 +49,7 @@ KeyNewUIDDialog::KeyNewUIDDialog(int channel, const KeyId& key_id, create_button_ = new QPushButton("Create"); error_label_ = new QLabel(); - auto grid_layout = new QGridLayout(); + auto* grid_layout = new QGridLayout(); grid_layout->addWidget(new QLabel(tr("Name")), 0, 0); grid_layout->addWidget(new QLabel(tr("Email")), 1, 0); grid_layout->addWidget(new QLabel(tr("Comment")), 2, 0); diff --git a/src/ui/dialog/keypair_details/KeyNewUIDDialog.h b/src/ui/dialog/keypair_details/KeyNewUIDDialog.h index 45124665..f298a46b 100644 --- a/src/ui/dialog/keypair_details/KeyNewUIDDialog.h +++ b/src/ui/dialog/keypair_details/KeyNewUIDDialog.h @@ -45,7 +45,7 @@ class KeyNewUIDDialog : public GeneralDialog { * @param key * @param parent */ - KeyNewUIDDialog(int channel, const KeyId& key, QWidget* parent = nullptr); + KeyNewUIDDialog(int channel, GpgKeyPtr key, QWidget* parent = nullptr); signals: /** @@ -64,7 +64,7 @@ class KeyNewUIDDialog : public GeneralDialog { private: int current_gpg_context_channel_; - GpgKey m_key_; ///< + GpgKeyPtr m_key_; ///< QLineEdit* name_{}; ///< QLineEdit* email_{}; ///< @@ -85,6 +85,6 @@ class KeyNewUIDDialog : public GeneralDialog { * @return true * @return false */ - bool check_email_address(const QString& str); + auto check_email_address(const QString& str) -> bool; }; } // namespace GpgFrontend::UI diff --git a/src/ui/dialog/keypair_details/KeyPairDetailTab.cpp b/src/ui/dialog/keypair_details/KeyPairDetailTab.cpp index 5a646ec0..fcdc139e 100644 --- a/src/ui/dialog/keypair_details/KeyPairDetailTab.cpp +++ b/src/ui/dialog/keypair_details/KeyPairDetailTab.cpp @@ -28,23 +28,21 @@ #include "KeyPairDetailTab.h" -#include "core/GpgModel.h" +#include + #include "core/function/GlobalSettingStation.h" #include "core/function/gpg/GpgKeyGetter.h" #include "core/model/GpgKey.h" #include "core/module/ModuleManager.h" -#include "core/thread/TaskRunnerGetter.h" #include "core/utils/CommonUtils.h" #include "ui/UISignalStation.h" namespace GpgFrontend::UI { -KeyPairDetailTab::KeyPairDetailTab(int channel, const QString& key_id, - QWidget* parent) +KeyPairDetailTab::KeyPairDetailTab(int channel, GpgKeyPtr key, QWidget* parent) : QWidget(parent), current_gpg_context_channel_(channel), - key_(GpgKeyGetter::GetInstance(current_gpg_context_channel_) - .GetKey(key_id)) { - assert(key_.IsGood()); + key_(std::move(key)) { + assert(key_->IsGood()); owner_box_ = new QGroupBox(tr("Owner")); key_box_ = new QGroupBox(tr("Primary Key")); @@ -183,8 +181,8 @@ void KeyPairDetailTab::slot_copy_fingerprint() { void KeyPairDetailTab::slot_refresh_key_info() { // Show the situation that primary key not exists. primary_key_exist_var_label_->setText( - key_.IsHasMasterKey() ? tr("Exists") : tr("Not Exists")); - if (!key_.IsHasMasterKey()) { + key_->IsHasMasterKey() ? tr("Exists") : tr("Not Exists")); + if (!key_->IsHasMasterKey()) { auto palette_expired = primary_key_exist_var_label_->palette(); palette_expired.setColor(primary_key_exist_var_label_->foregroundRole(), Qt::red); @@ -196,7 +194,7 @@ void KeyPairDetailTab::slot_refresh_key_info() { primary_key_exist_var_label_->setPalette(palette_valid); } - if (key_.IsExpired()) { + if (key_->IsExpired()) { auto palette_expired = expire_var_label_->palette(); palette_expired.setColor(expire_var_label_->foregroundRole(), Qt::red); expire_var_label_->setPalette(palette_expired); @@ -206,42 +204,42 @@ void KeyPairDetailTab::slot_refresh_key_info() { expire_var_label_->setPalette(palette_valid); } - name_var_label_->setText(key_.Name()); - email_var_label_->setText(key_.Email()); + name_var_label_->setText(key_->Name()); + email_var_label_->setText(key_->Email()); - comment_var_label_->setText(key_.Comment()); - key_id_var_label_->setText(key_.ID()); + comment_var_label_->setText(key_->Comment()); + key_id_var_label_->setText(key_->ID()); QString buffer; QTextStream usage_steam(&buffer); - if (key_.IsHasCertCap()) { + if (key_->IsHasCertCap()) { usage_steam << tr("Certificate") << " "; } - if (key_.IsHasEncrCap()) usage_steam << tr("Encrypt") << " "; - if (key_.IsHasSignCap()) usage_steam << tr("Sign") << " "; - if (key_.IsHasAuthCap()) usage_steam << tr("Auth") << " "; + if (key_->IsHasEncrCap()) usage_steam << tr("Encrypt") << " "; + if (key_->IsHasSignCap()) usage_steam << tr("Sign") << " "; + if (key_->IsHasAuthCap()) usage_steam << tr("Auth") << " "; usage_var_label_->setText(usage_steam.readAll()); QString buffer_2; QTextStream actual_usage_steam(&buffer_2); - if (key_.IsHasActualCertCap()) { + if (key_->IsHasActualCertCap()) { actual_usage_steam << tr("Certificate") << " "; } - if (key_.IsHasActualEncrCap()) { + if (key_->IsHasActualEncrCap()) { actual_usage_steam << tr("Encrypt") << " "; } - if (key_.IsHasActualSignCap()) { + if (key_->IsHasActualSignCap()) { actual_usage_steam << tr("Sign") << " "; } - if (key_.IsHasActualAuthCap()) { + if (key_->IsHasActualAuthCap()) { actual_usage_steam << tr("Auth") << " "; } actual_usage_var_label_->setText(actual_usage_steam.readAll()); - owner_trust_var_label_->setText(key_.OwnerTrust()); + owner_trust_var_label_->setText(key_->OwnerTrust()); QString key_size_val; QString key_expire_val; @@ -250,41 +248,41 @@ void KeyPairDetailTab::slot_refresh_key_info() { QString key_algo_detail_val; QString key_last_update_val; - key_size_val = QString::number(key_.PrimaryKeyLength()); + key_size_val = QString::number(key_->PrimaryKeyLength()); - if (key_.ExpirationTime().toSecsSinceEpoch() == 0) { + if (key_->ExpirationTime().toSecsSinceEpoch() == 0) { expire_var_label_->setText(tr("Never Expire")); } else { - expire_var_label_->setText(QLocale().toString((key_.ExpirationTime()))); + expire_var_label_->setText(QLocale().toString((key_->ExpirationTime()))); } - key_algo_val = key_.PublicKeyAlgo(); - key_algo_detail_val = key_.Algo(); + key_algo_val = key_->PublicKeyAlgo(); + key_algo_detail_val = key_->Algo(); - created_var_label_->setText(QLocale().toString(key_.CreationTime())); + created_var_label_->setText(QLocale().toString(key_->CreationTime())); - if (key_.LastUpdateTime().toSecsSinceEpoch() == 0) { + if (key_->LastUpdateTime().toSecsSinceEpoch() == 0) { last_update_var_label_->setText(tr("No Data")); } else { - last_update_var_label_->setText(QLocale().toString(key_.LastUpdateTime())); + last_update_var_label_->setText(QLocale().toString(key_->LastUpdateTime())); } key_size_var_label_->setText(key_size_val); algorithm_var_label_->setText(key_algo_val); algorithm_detail_var_label_->setText(key_algo_detail_val); - fingerprint_var_label_->setText(BeautifyFingerprint(key_.Fingerprint())); + fingerprint_var_label_->setText(BeautifyFingerprint(key_->Fingerprint())); fingerprint_var_label_->setWordWrap(true); // for x448 and ed448 icon_label_->hide(); exp_label_->hide(); - if (key_.IsExpired()) { + if (key_->IsExpired()) { slot_refresh_notice(":/icons/warning.png", tr("Warning: The primary key has expired.")); - } else if (key_.IsRevoked()) { + } else if (key_->IsRevoked()) { slot_refresh_notice(":/icons/warning.png", tr("Warning: The primary key has been revoked.")); - } else if (key_.IsPrivateKey() && !key_.IsHasMasterKey()) { + } else if (key_->IsPrivateKey() && !key_->IsHasMasterKey()) { slot_refresh_notice(":/icons/warning.png", tr("Warning: The primary key is not exists.")); } else { @@ -294,9 +292,9 @@ void KeyPairDetailTab::slot_refresh_key_info() { void KeyPairDetailTab::slot_refresh_key() { // refresh the key - GpgKey refreshed_key = - GpgKeyGetter::GetInstance(current_gpg_context_channel_).GetKey(key_.ID()); - assert(refreshed_key.IsGood()); + auto refreshed_key = GpgKeyGetter::GetInstance(current_gpg_context_channel_) + .GetKeyPtr(key_->ID()); + assert(refreshed_key != nullptr); std::swap(this->key_, refreshed_key); @@ -316,7 +314,7 @@ void KeyPairDetailTab::slot_query_key_publish_state() { return; } - const auto fpr = key_.Fingerprint(); + const auto fpr = key_->Fingerprint(); Module::TriggerEvent( "REQUEST_GET_PUBLIC_KEY_BY_FINGERPRINT", diff --git a/src/ui/dialog/keypair_details/KeyPairDetailTab.h b/src/ui/dialog/keypair_details/KeyPairDetailTab.h index da58e36e..d388a4af 100644 --- a/src/ui/dialog/keypair_details/KeyPairDetailTab.h +++ b/src/ui/dialog/keypair_details/KeyPairDetailTab.h @@ -29,6 +29,7 @@ #pragma once #include "core/model/GpgKey.h" +#include "core/typedef/GpgTypedef.h" namespace GpgFrontend::UI { @@ -68,7 +69,7 @@ class KeyPairDetailTab : public QWidget { private: int current_gpg_context_channel_; - GpgKey key_; ///< + GpgKeyPtr key_; ///< QGroupBox* owner_box_; ///< Groupbox containing owner information QGroupBox* key_box_; ///< Groupbox containing key information @@ -103,7 +104,7 @@ class KeyPairDetailTab : public QWidget { * @param key_id * @param parent */ - explicit KeyPairDetailTab(int channel, const QString& key_id, + explicit KeyPairDetailTab(int channel, GpgKeyPtr key, QWidget* parent = nullptr); }; diff --git a/src/ui/dialog/keypair_details/KeyPairOperaTab.cpp b/src/ui/dialog/keypair_details/KeyPairOperaTab.cpp index 936997a9..dddbb545 100644 --- a/src/ui/dialog/keypair_details/KeyPairOperaTab.cpp +++ b/src/ui/dialog/keypair_details/KeyPairOperaTab.cpp @@ -30,7 +30,6 @@ #include "KeySetExpireDateDialog.h" #include "core/function/GlobalSettingStation.h" -#include "core/function/gpg//GpgKeyGetter.h" #include "core/function/gpg/GpgKeyImportExporter.h" #include "core/function/gpg/GpgKeyOpera.h" #include "core/model/GpgKey.h" @@ -46,13 +45,9 @@ namespace GpgFrontend::UI { -KeyPairOperaTab::KeyPairOperaTab(int channel, const QString& key_id, - QWidget* parent) - : QWidget(parent), - current_gpg_context_channel_(channel), - m_key_(GpgKeyGetter::GetInstance(current_gpg_context_channel_) - .GetKey(key_id)) { - assert(m_key_.IsGood()); +KeyPairOperaTab::KeyPairOperaTab(int channel, GpgKeyPtr key, QWidget* parent) + : QWidget(parent), current_gpg_context_channel_(channel), m_key_(key) { + assert(m_key_ != nullptr); // Set Menu CreateOperaMenu(); @@ -69,13 +64,13 @@ KeyPairOperaTab::KeyPairOperaTab(int channel, const QString& key_id, connect(export_public_button, &QPushButton::clicked, this, &KeyPairOperaTab::slot_export_public_key); - if (m_key_.IsPrivateKey()) { + if (m_key_->IsPrivateKey()) { auto* export_private_button = new QPushButton(tr("Export Private Key")); export_private_button->setStyleSheet("text-align:center;"); export_private_button->setMenu(secret_key_export_opera_menu_); export_h_box_layout->addWidget(export_private_button); - if (m_key_.IsHasMasterKey()) { + if (m_key_->IsHasMasterKey()) { auto* edit_expires_button = new QPushButton(tr("Modify Expiration Datetime (Primary Key)")); connect(edit_expires_button, &QPushButton::clicked, this, @@ -104,7 +99,7 @@ KeyPairOperaTab::KeyPairOperaTab(int channel, const QString& key_id, advance_h_box_layout->addWidget(key_server_opera_button); if (Module::IsModuleActivate(kPaperKeyModuleID)) { - if (!m_key_.IsPrivateKey()) { + if (!m_key_->IsPrivateKey()) { auto* import_paper_key_button = new QPushButton(tr("Import A Paper Key")); import_paper_key_button->setStyleSheet("text-align:center;"); connect(import_paper_key_button, &QPushButton::clicked, this, @@ -113,7 +108,7 @@ KeyPairOperaTab::KeyPairOperaTab(int channel, const QString& key_id, } } - if (m_key_.IsPrivateKey() && m_key_.IsHasMasterKey()) { + if (m_key_->IsPrivateKey() && m_key_->IsHasMasterKey()) { auto* revoke_cert_opera_button = new QPushButton(tr("Revoke Certificate Operation")); revoke_cert_opera_button->setStyleSheet("text-align:center;"); @@ -136,7 +131,8 @@ KeyPairOperaTab::KeyPairOperaTab(int channel, const QString& key_id, opera_key_box->setLayout(vbox_p_k); m_vbox->addWidget(opera_key_box); // modify owner trust of public key - if (!m_key_.IsPrivateKey()) vbox_p_k->addWidget(set_owner_trust_level_button); + if (!m_key_->IsPrivateKey()) + vbox_p_k->addWidget(set_owner_trust_level_button); vbox_p_k->addWidget(modify_tofu_button); m_vbox->addStretch(0); @@ -155,7 +151,7 @@ void KeyPairOperaTab::CreateOperaMenu() { new QAction(tr("Publish Public Key to Key Server"), this); connect(upload_key_pair, &QAction::triggered, this, &KeyPairOperaTab::slot_publish_key_to_server); - if (!(m_key_.IsPrivateKey() && m_key_.IsHasMasterKey())) { + if (!(m_key_->IsPrivateKey() && m_key_->IsHasMasterKey())) { upload_key_pair->setDisabled(true); } @@ -165,7 +161,7 @@ void KeyPairOperaTab::CreateOperaMenu() { &KeyPairOperaTab::slot_update_key_from_server); // when a key has primary key, it should always upload to keyserver. - if (m_key_.IsHasMasterKey()) { + if (m_key_->IsHasMasterKey()) { update_key_pair->setDisabled(true); } @@ -178,7 +174,7 @@ void KeyPairOperaTab::CreateOperaMenu() { new QAction(tr("Export Full Secret Key"), this); connect(export_full_secret_key, &QAction::triggered, this, &KeyPairOperaTab::slot_export_private_key); - if (!m_key_.IsPrivateKey()) export_full_secret_key->setDisabled(true); + if (!m_key_->IsPrivateKey()) export_full_secret_key->setDisabled(true); auto* export_shortest_secret_key = new QAction(tr("Export Shortest Secret Key"), this); @@ -189,12 +185,12 @@ void KeyPairOperaTab::CreateOperaMenu() { secret_key_export_opera_menu_->addAction(export_shortest_secret_key); // only work with RSA - if (m_key_.Algo() == "RSA" && Module::IsModuleActivate(kPaperKeyModuleID)) { + if (m_key_->Algo() == "RSA" && Module::IsModuleActivate(kPaperKeyModuleID)) { auto* export_secret_key_as_paper_key = new QAction( tr("Export Secret Key As A Paper Key") + QString(" (BETA)"), this); connect(export_secret_key_as_paper_key, &QAction::triggered, this, &KeyPairOperaTab::slot_export_paper_key); - if (!m_key_.IsPrivateKey()) { + if (!m_key_->IsPrivateKey()) { export_secret_key_as_paper_key->setDisabled(true); } secret_key_export_opera_menu_->addAction(export_secret_key_as_paper_key); @@ -228,11 +224,11 @@ void KeyPairOperaTab::slot_export_public_key() { // generate a file name #if defined(_WIN32) || defined(WIN32) - auto file_string = - m_key_.Name() + "[" + m_key_.Email() + "](" + m_key_.ID() + ")_pub.asc"; + auto file_string = m_key_->Name() + "[" + m_key_->Email() + "](" + + m_key_->ID() + ")_pub.asc"; #else - auto file_string = - m_key_.Name() + "<" + m_key_.Email() + ">(" + m_key_.ID() + ")_pub.asc"; + auto file_string = m_key_->Name() + "<" + m_key_->Email() + ">(" + + m_key_->ID() + ")_pub.asc"; #endif std::replace(file_string.begin(), file_string.end(), ' ', '_'); @@ -277,11 +273,11 @@ void KeyPairOperaTab::slot_export_short_private_key() { // generate a file name #if defined(_WIN32) || defined(WIN32) - auto file_string = m_key_.Name() + "[" + m_key_.Email() + "](" + - m_key_.ID() + ")_short_secret.asc"; + auto file_string = m_key_->Name() + "[" + m_key_->Email() + "](" + + m_key_->ID() + ")_short_secret.asc"; #else - auto file_string = m_key_.Name() + "<" + m_key_.Email() + ">(" + - m_key_.ID() + ")_short_secret.asc"; + auto file_string = m_key_->Name() + "<" + m_key_->Email() + ">(" + + m_key_->ID() + ")_short_secret.asc"; #endif std::replace(file_string.begin(), file_string.end(), ' ', '_'); @@ -328,11 +324,11 @@ void KeyPairOperaTab::slot_export_private_key() { // generate a file name #if defined(_WIN32) || defined(WIN32) - auto file_string = m_key_.Name() + "[" + m_key_.Email() + "](" + - m_key_.ID() + ")_full_secret.asc"; + auto file_string = m_key_->Name() + "[" + m_key_->Email() + "](" + + m_key_->ID() + ")_full_secret.asc"; #else - auto file_string = m_key_.Name() + "<" + m_key_.Email() + ">(" + - m_key_.ID() + ")_full_secret.asc"; + auto file_string = m_key_->Name() + "<" + m_key_->Email() + ">(" + + m_key_->ID() + ")_full_secret.asc"; #endif std::replace(file_string.begin(), file_string.end(), ' ', '_'); @@ -351,8 +347,8 @@ void KeyPairOperaTab::slot_export_private_key() { } void KeyPairOperaTab::slot_modify_edit_datetime() { - auto* dialog = new KeySetExpireDateDialog(current_gpg_context_channel_, - m_key_.ID(), this); + auto* dialog = + new KeySetExpireDateDialog(current_gpg_context_channel_, m_key_, this); dialog->show(); } @@ -362,7 +358,7 @@ void KeyPairOperaTab::slot_publish_key_to_server() { GpgKeyImportExporter::GetInstance(current_gpg_context_channel_) .ExportKey(m_key_, false, true, false); - auto fpr = m_key_.Fingerprint(); + auto fpr = m_key_->Fingerprint(); auto key_text = gf_buffer.ConvertToQByteArray(); Module::TriggerEvent( @@ -434,8 +430,9 @@ void KeyPairOperaTab::slot_publish_key_to_server() { return; } - auto keys = KeyIdArgsList{m_key_.ID()}; - auto* dialog = new KeyUploadDialog(current_gpg_context_channel_, keys, this); + auto keys = KeyIdArgsList{m_key_->ID()}; + auto* dialog = + new KeyUploadDialog(current_gpg_context_channel_, {m_key_}, this); dialog->show(); dialog->SlotUpload(); } @@ -443,11 +440,11 @@ void KeyPairOperaTab::slot_publish_key_to_server() { void KeyPairOperaTab::slot_update_key_from_server() { if (Module::IsModuleActivate(kKeyServerSyncModuleID)) { CommonUtils::GetInstance()->ImportKeyByKeyServerSyncModule( - this, current_gpg_context_channel_, {m_key_.Fingerprint()}); + this, current_gpg_context_channel_, {m_key_->Fingerprint()}); return; } - CommonUtils::GetInstance()->ImportKeyFromKeyServer( - current_gpg_context_channel_, {m_key_.ID()}); + CommonUtils::GetInstance()->ImportGpgKeyFromKeyServer( + current_gpg_context_channel_, {m_key_}); } void KeyPairOperaTab::slot_gen_revoke_cert() { @@ -464,11 +461,11 @@ void KeyPairOperaTab::slot_gen_revoke_cert() { QString m_output_file_name; #if defined(_WIN32) || defined(WIN32) - auto file_string = m_key_.Name() + "[" + m_key_.Email() + "](" + - m_key_.ID() + ").rev"; + auto file_string = m_key_->Name() + "[" + m_key_->Email() + "](" + + m_key_->ID() + ").rev"; #else - auto file_string = m_key_.Name() + "<" + m_key_.Email() + - ">(" + m_key_.ID() + ").rev"; + auto file_string = m_key_->Name() + "<" + m_key_->Email() + + ">(" + m_key_->ID() + ").rev"; #endif QFileDialog dialog(this, tr("Generate revocation certificate"), @@ -529,7 +526,7 @@ void KeyPairOperaTab::slot_modify_tofu_policy() { void KeyPairOperaTab::slot_set_owner_trust_level() { auto* function = new SetOwnerTrustLevel(this); - function->Exec(current_gpg_context_channel_, m_key_.ID()); + function->Exec(current_gpg_context_channel_, m_key_); function->deleteLater(); } @@ -581,7 +578,7 @@ void KeyPairOperaTab::slot_import_revoke_cert() { return; } - emit UISignalStation::GetInstance() -> SignalKeyRevoked(m_key_.ID()); + emit UISignalStation::GetInstance() -> SignalKeyRevoked(m_key_->ID()); CommonUtils::GetInstance()->SlotImportKeys( nullptr, current_gpg_context_channel_, rev_file.readAll()); } @@ -620,11 +617,11 @@ void KeyPairOperaTab::slot_export_paper_key() { // generate a file name #if defined(_WIN32) || defined(WIN32) - auto file_string = m_key_.Name() + "[" + m_key_.Email() + "](" + - m_key_.ID() + ")_paper_key.txt"; + auto file_string = m_key_->Name() + "[" + m_key_->Email() + "](" + + m_key_->ID() + ")_paper_key.txt"; #else - auto file_string = m_key_.Name() + "<" + m_key_.Email() + ">(" + - m_key_.ID() + ")_paper_key.txt"; + auto file_string = m_key_->Name() + "<" + m_key_->Email() + ">(" + + m_key_->ID() + ")_paper_key.txt"; #endif std::replace(file_string.begin(), file_string.end(), ' ', '_'); @@ -674,11 +671,11 @@ void KeyPairOperaTab::slot_import_paper_key() { // generate a file name #if defined(_WIN32) || defined(WIN32) - auto file_string = m_key_.Name() + "[" + m_key_.Email() + "](" + m_key_.ID() + - ")_paper_key.txt"; + auto file_string = m_key_->Name() + "[" + m_key_->Email() + "](" + + m_key_->ID() + ")_paper_key.txt"; #else - auto file_string = m_key_.Name() + "<" + m_key_.Email() + ">(" + m_key_.ID() + - ")_paper_key.txt"; + auto file_string = m_key_->Name() + "<" + m_key_->Email() + ">(" + + m_key_->ID() + ")_paper_key.txt"; #endif std::replace(file_string.begin(), file_string.end(), ' ', '_'); diff --git a/src/ui/dialog/keypair_details/KeyPairOperaTab.h b/src/ui/dialog/keypair_details/KeyPairOperaTab.h index 9e1f2a23..729a7d74 100644 --- a/src/ui/dialog/keypair_details/KeyPairOperaTab.h +++ b/src/ui/dialog/keypair_details/KeyPairOperaTab.h @@ -28,7 +28,7 @@ #pragma once -#include "core/model/GpgKey.h" +#include "core/typedef/GpgTypedef.h" namespace GpgFrontend { class GpgImportInformation; @@ -44,7 +44,7 @@ class KeyPairOperaTab : public QWidget { * @param key_id * @param parent */ - KeyPairOperaTab(int channel, const QString& key_id, QWidget* parent); + KeyPairOperaTab(int channel, GpgKeyPtr key, QWidget* parent); /** * @brief Create a Opera Menu object @@ -140,10 +140,9 @@ class KeyPairOperaTab : public QWidget { private: int current_gpg_context_channel_; - GpgKey m_key_; ///< + GpgKeyPtr m_key_; ///< QMenu* key_server_opera_menu_{}; ///< QMenu* rev_cert_opera_menu_{}; QMenu* secret_key_export_opera_menu_{}; ///< - }; } // namespace GpgFrontend::UI diff --git a/src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp b/src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp index c4e93b62..011ea1ed 100644 --- a/src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp +++ b/src/ui/dialog/keypair_details/KeyPairSubkeyTab.cpp @@ -28,7 +28,8 @@ #include "KeyPairSubkeyTab.h" -#include "core/GpgModel.h" +#include + #include "core/function/gpg/GpgKeyGetter.h" #include "core/function/gpg/GpgKeyImportExporter.h" #include "core/function/gpg/GpgKeyManager.h" @@ -43,13 +44,11 @@ namespace GpgFrontend::UI { -KeyPairSubkeyTab::KeyPairSubkeyTab(int channel, const QString& key_id, - QWidget* parent) +KeyPairSubkeyTab::KeyPairSubkeyTab(int channel, GpgKeyPtr key, QWidget* parent) : QWidget(parent), current_gpg_context_channel_(channel), - key_(GpgKeyGetter::GetInstance(current_gpg_context_channel_) - .GetKey(key_id)) { - assert(key_.IsGood()); + key_(std::move(key)) { + assert(key_ != nullptr); create_subkey_list(); create_subkey_opera_menu(); @@ -61,7 +60,7 @@ KeyPairSubkeyTab::KeyPairSubkeyTab(int channel, const QString& key_id, auto* add_subkey_button = new QPushButton(tr("New Subkey")); auto* add_adsk_button = new QPushButton(tr("Add ADSK(s)")); - if (!key_.IsPrivateKey() || !key_.IsHasMasterKey()) { + if (!key_->IsPrivateKey() || !key_->IsHasMasterKey()) { add_subkey_button->setDisabled(true); add_subkey_button->hide(); @@ -202,7 +201,7 @@ void KeyPairSubkeyTab::slot_refresh_subkey_list() { subkey_list_->setSelectionMode(QAbstractItemView::SingleSelection); this->buffered_subkeys_.clear(); - for (auto& s_key : key_.SubKeys()) { + for (auto& s_key : key_->SubKeys()) { this->buffered_subkeys_.push_back(std::move(s_key)); } @@ -281,14 +280,14 @@ void KeyPairSubkeyTab::slot_refresh_subkey_list() { void KeyPairSubkeyTab::slot_add_subkey() { auto* dialog = - new SubkeyGenerateDialog(current_gpg_context_channel_, key_.ID(), this); + new SubkeyGenerateDialog(current_gpg_context_channel_, key_, this); dialog->show(); } void KeyPairSubkeyTab::slot_add_adsk() { QStringList except_key_ids; - except_key_ids.append(key_.ID()); - for (const auto& s_key : key_.SubKeys()) { + except_key_ids.append(key_->ID()); + for (const auto& s_key : key_->SubKeys()) { except_key_ids.append(s_key.ID()); } @@ -382,7 +381,7 @@ void KeyPairSubkeyTab::slot_refresh_subkey_detail() { QString buffer; QTextStream usage_steam(&buffer); - usage_var_label_->setText(GetUsagesBySubkey(s_key)); + usage_var_label_->setText(GetUsagesByAbstractKey(&s_key)); // Show the situation that secret key not exists. master_key_exist_var_label_->setText(s_key.IsSecretKey() ? tr("Exists") @@ -424,7 +423,7 @@ void KeyPairSubkeyTab::slot_refresh_subkey_detail() { export_subkey_button_->setText(s_key.IsHasCertCap() ? tr("Export Primary Key") : tr("Export Subkey")); export_subkey_button_->setDisabled( - !key_.IsPrivateKey() || s_key.IsHasCertCap() || !s_key.IsSecretKey()); + !key_->IsPrivateKey() || s_key.IsHasCertCap() || !s_key.IsSecretKey()); key_type_var_label_->setText(s_key.IsHasCertCap() ? tr("Primary Key") : tr("Subkey")); @@ -467,14 +466,14 @@ void KeyPairSubkeyTab::create_subkey_opera_menu() { void KeyPairSubkeyTab::slot_edit_subkey() { auto* dialog = - new KeySetExpireDateDialog(current_gpg_context_channel_, key_.ID(), + new KeySetExpireDateDialog(current_gpg_context_channel_, key_, get_selected_subkey().Fingerprint(), this); dialog->show(); } void KeyPairSubkeyTab::contextMenuEvent(QContextMenuEvent* event) { // must have primary key before do any actions on subkey - if (key_.IsHasMasterKey() && !subkey_list_->selectedItems().isEmpty()) { + if (key_->IsHasMasterKey() && !subkey_list_->selectedItems().isEmpty()) { const auto& s_key = get_selected_subkey(); if (s_key.IsHasCertCap()) return; @@ -501,9 +500,9 @@ auto KeyPairSubkeyTab::get_selected_subkey() -> const GpgSubKey& { } void KeyPairSubkeyTab::slot_refresh_key_info() { - key_ = - GpgKeyGetter::GetInstance(current_gpg_context_channel_).GetKey(key_.ID()); - assert(key_.IsGood()); + key_ = GpgKeyGetter::GetInstance(current_gpg_context_channel_) + .GetKeyPtr(key_->ID()); + assert(key_ != nullptr); } void KeyPairSubkeyTab::slot_export_subkey() { @@ -532,10 +531,10 @@ void KeyPairSubkeyTab::slot_export_subkey() { // generate a file name #if defined(_WIN32) || defined(WIN32) auto file_string = - key_.Name() + "[" + key_.Email() + "](" + s_key.ID() + ")_s_key.asc"; + key_->Name() + "[" + key_->Email() + "](" + s_key.ID() + ")_s_key.asc"; #else auto file_string = - key_.Name() + "<" + key_.Email() + ">(" + s_key.ID() + ")_s_key.asc"; + key_->Name() + "<" + key_->Email() + ">(" + s_key.ID() + ")_s_key.asc"; #endif std::replace(file_string.begin(), file_string.end(), ' ', '_'); @@ -567,7 +566,7 @@ void KeyPairSubkeyTab::slot_delete_subkey() { if (ret != QMessageBox::Yes) return; int index = 0; - for (const auto& sk : key_.SubKeys()) { + for (const auto& sk : key_->SubKeys()) { if (sk.Fingerprint() == s_key.Fingerprint()) { break; } @@ -616,7 +615,7 @@ void KeyPairSubkeyTab::slot_revoke_subkey() { if (ret != QMessageBox::Yes) return; int index = 0; - for (const auto& sk : key_.SubKeys()) { + for (const auto& sk : key_->SubKeys()) { if (sk.Fingerprint() == s_key.Fingerprint()) { break; } diff --git a/src/ui/dialog/keypair_details/KeyPairSubkeyTab.h b/src/ui/dialog/keypair_details/KeyPairSubkeyTab.h index d06ee032..3d9eeb50 100644 --- a/src/ui/dialog/keypair_details/KeyPairSubkeyTab.h +++ b/src/ui/dialog/keypair_details/KeyPairSubkeyTab.h @@ -45,7 +45,7 @@ class KeyPairSubkeyTab : public QWidget { * @param key * @param parent */ - KeyPairSubkeyTab(int channel, const QString& key, QWidget* parent); + KeyPairSubkeyTab(int channel, GpgKeyPtr key, QWidget* parent); private: /** @@ -68,7 +68,7 @@ class KeyPairSubkeyTab : public QWidget { auto get_selected_subkey() -> const GpgSubKey&; int current_gpg_context_channel_; - GpgKey key_; ///< + GpgKeyPtr key_; ///< QTableWidget* subkey_list_{}; ///< QContainer buffered_subkeys_; ///< diff --git a/src/ui/dialog/keypair_details/KeyPairUIDTab.cpp b/src/ui/dialog/keypair_details/KeyPairUIDTab.cpp index a010a6ea..73428f39 100644 --- a/src/ui/dialog/keypair_details/KeyPairUIDTab.cpp +++ b/src/ui/dialog/keypair_details/KeyPairUIDTab.cpp @@ -28,7 +28,8 @@ #include "KeyPairUIDTab.h" -#include "core/GpgModel.h" +#include + #include "core/function/gpg/GpgKeyGetter.h" #include "core/function/gpg/GpgKeyManager.h" #include "core/function/gpg/GpgUIDOperator.h" @@ -40,13 +41,11 @@ namespace GpgFrontend::UI { -KeyPairUIDTab::KeyPairUIDTab(int channel, const QString& key_id, - QWidget* parent) +KeyPairUIDTab::KeyPairUIDTab(int channel, GpgKeyPtr key, QWidget* parent) : QWidget(parent), current_gpg_context_channel_(channel), - m_key_(GpgKeyGetter::GetInstance(current_gpg_context_channel_) - .GetKey(key_id)) { - assert(m_key_.IsGood()); + m_key_(std::move(key)) { + assert(m_key_ != nullptr); create_uid_list(); create_sign_list(); @@ -57,7 +56,7 @@ KeyPairUIDTab::KeyPairUIDTab(int channel, const QString& key_id, auto* add_uid_button = new QPushButton(tr("New UID")); - if (!m_key_.IsHasMasterKey()) { + if (!m_key_->IsHasMasterKey()) { add_uid_button->setDisabled(true); } uid_buttons_layout->addWidget(add_uid_button); @@ -176,7 +175,7 @@ void KeyPairUIDTab::slot_refresh_uid_list() { this->buffered_uids_.clear(); - for (auto& uid : m_key_.UIDs()) { + for (auto& uid : m_key_->UIDs()) { this->buffered_uids_.push_back(std::move(uid)); } @@ -316,7 +315,7 @@ void KeyPairUIDTab::slot_add_sign() { void KeyPairUIDTab::slot_add_uid() { auto* key_new_uid_dialog = - new KeyNewUIDDialog(current_gpg_context_channel_, m_key_.ID(), this); + new KeyNewUIDDialog(current_gpg_context_channel_, m_key_, this); connect(key_new_uid_dialog, &KeyNewUIDDialog::finished, this, &KeyPairUIDTab::slot_add_uid_result); connect(key_new_uid_dialog, &KeyNewUIDDialog::finished, key_new_uid_dialog, @@ -434,7 +433,7 @@ void KeyPairUIDTab::create_uid_popup_menu() { connect(del_uid_act_, &QAction::triggered, this, &KeyPairUIDTab::slot_del_uid); - if (m_key_.IsHasMasterKey()) { + if (m_key_->IsHasMasterKey()) { uid_popup_menu_->addAction(set_primary_uid_act_); uid_popup_menu_->addAction(sign_uid_act_); uid_popup_menu_->addAction(rev_uid_act_); @@ -516,9 +515,9 @@ void KeyPairUIDTab::slot_del_sign() { void KeyPairUIDTab::slot_refresh_key() { // refresh the key - GpgKey refreshed_key = GpgKeyGetter::GetInstance(current_gpg_context_channel_) - .GetKey(m_key_.ID()); - assert(refreshed_key.IsGood()); + auto refreshed_key = GpgKeyGetter::GetInstance(current_gpg_context_channel_) + .GetKeyPtr(m_key_->ID()); + assert(refreshed_key != nullptr); std::swap(this->m_key_, refreshed_key); @@ -537,7 +536,7 @@ void KeyPairUIDTab::slot_rev_uid() { return; } - const auto uids = m_key_.UIDs(); + const auto uids = m_key_->UIDs(); QString message = tr("

Revoke UID Confirmation


" "UID: %1

" diff --git a/src/ui/dialog/keypair_details/KeyPairUIDTab.h b/src/ui/dialog/keypair_details/KeyPairUIDTab.h index 3f98e54b..ecae16b5 100644 --- a/src/ui/dialog/keypair_details/KeyPairUIDTab.h +++ b/src/ui/dialog/keypair_details/KeyPairUIDTab.h @@ -43,7 +43,7 @@ class KeyPairUIDTab : public QWidget { * @param key_id * @param parent */ - KeyPairUIDTab(int channel, const QString& key_id, QWidget* parent); + KeyPairUIDTab(int channel, GpgKeyPtr key, QWidget* parent); signals: @@ -138,7 +138,7 @@ class KeyPairUIDTab : public QWidget { private: int current_gpg_context_channel_; - GpgKey m_key_; + GpgKeyPtr m_key_; QTableWidget* uid_list_{}; ///< QTableWidget* sig_list_{}; ///< QTabWidget* tofu_tabs_{}; ///< diff --git a/src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp b/src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp index 4880bd3d..b2d8d424 100644 --- a/src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp +++ b/src/ui/dialog/keypair_details/KeySetExpireDateDialog.cpp @@ -28,8 +28,9 @@ #include "KeySetExpireDateDialog.h" +#include + #include "core/function/GlobalSettingStation.h" -#include "core/function/gpg/GpgKeyGetter.h" #include "core/function/gpg/GpgKeyOpera.h" #include "core/utils/GpgUtils.h" #include "ui/UISignalStation.h" @@ -37,29 +38,27 @@ namespace GpgFrontend::UI { -KeySetExpireDateDialog::KeySetExpireDateDialog(int channel, const KeyId& key_id, +KeySetExpireDateDialog::KeySetExpireDateDialog(int channel, GpgKeyPtr key, QWidget* parent) : GeneralDialog(typeid(KeySetExpireDateDialog).name(), parent), ui_(GpgFrontend::SecureCreateSharedObject< Ui_ModifiedExpirationDateTime>()), current_gpg_context_channel_(channel), - m_key_(GpgKeyGetter::GetInstance(current_gpg_context_channel_) - .GetKey(key_id)) { - assert(m_key_.IsGood()); + m_key_(std::move(key)) { + assert(m_key_->IsGood()); init(); } -KeySetExpireDateDialog::KeySetExpireDateDialog(int channel, const KeyId& key_id, +KeySetExpireDateDialog::KeySetExpireDateDialog(int channel, GpgKeyPtr key, QString subkey_fpr, QWidget* parent) : GeneralDialog(typeid(KeySetExpireDateDialog).name(), parent), ui_(GpgFrontend::SecureCreateSharedObject< Ui_ModifiedExpirationDateTime>()), current_gpg_context_channel_(channel), - m_key_(GpgKeyGetter::GetInstance(current_gpg_context_channel_) - .GetKey(key_id)), + m_key_(std::move(key)), m_subkey_(std::move(subkey_fpr)) { - assert(m_key_.IsGood()); + assert(m_key_ != nullptr); init(); } @@ -101,7 +100,7 @@ void KeySetExpireDateDialog::init() { ui_->dateEdit->setMinimumDateTime(min_date_time); // set default date time to expire date time - auto current_expire_time = m_key_.ExpirationTime(); + auto current_expire_time = m_key_->ExpirationTime(); ui_->dateEdit->setDateTime(current_expire_time); ui_->timeEdit->setDateTime(current_expire_time); @@ -114,11 +113,11 @@ void KeySetExpireDateDialog::init() { UISignalStation::GetInstance(), &UISignalStation::SignalKeyDatabaseRefresh); - if (m_key_.ExpirationTime().toSecsSinceEpoch() == 0) { + if (m_key_->ExpirationTime().toSecsSinceEpoch() == 0) { ui_->noExpirationCheckBox->setCheckState(Qt::Checked); } else { - ui_->dateEdit->setDateTime(m_key_.ExpirationTime()); - ui_->timeEdit->setDateTime(m_key_.ExpirationTime()); + ui_->dateEdit->setDateTime(m_key_->ExpirationTime()); + ui_->timeEdit->setDateTime(m_key_->ExpirationTime()); } ui_->titleLabel->setText(tr("Modified Expiration Date (Local Time)")); diff --git a/src/ui/dialog/keypair_details/KeySetExpireDateDialog.h b/src/ui/dialog/keypair_details/KeySetExpireDateDialog.h index 6617ff83..b75339a0 100644 --- a/src/ui/dialog/keypair_details/KeySetExpireDateDialog.h +++ b/src/ui/dialog/keypair_details/KeySetExpireDateDialog.h @@ -47,7 +47,7 @@ class KeySetExpireDateDialog : public GeneralDialog { * @param key_id * @param parent */ - explicit KeySetExpireDateDialog(int channel, const KeyId& key_id, + explicit KeySetExpireDateDialog(int channel, GpgKeyPtr key_id, QWidget* parent = nullptr); /** @@ -57,7 +57,7 @@ class KeySetExpireDateDialog : public GeneralDialog { * @param subkey_fpr * @param parent */ - explicit KeySetExpireDateDialog(int channel, const KeyId& key_id, + explicit KeySetExpireDateDialog(int channel, GpgKeyPtr key, QString subkey_fpr, QWidget* parent = nullptr); @@ -77,7 +77,7 @@ class KeySetExpireDateDialog : public GeneralDialog { std::shared_ptr ui_; ///< int current_gpg_context_channel_; ///< - const GpgKey m_key_; ///< + const GpgKeyPtr m_key_; ///< const SubkeyId m_subkey_; ///< private slots: diff --git a/src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp b/src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp index 2c4a8c59..46027428 100644 --- a/src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp +++ b/src/ui/dialog/keypair_details/KeyUIDSignDialog.cpp @@ -28,22 +28,21 @@ #include "KeyUIDSignDialog.h" -#include "core/function/gpg/GpgKeyGetter.h" #include "core/function/gpg/GpgKeyManager.h" #include "ui/UISignalStation.h" #include "ui/widgets/KeyList.h" namespace GpgFrontend::UI { -KeyUIDSignDialog::KeyUIDSignDialog(int channel, const GpgKey& key, +KeyUIDSignDialog::KeyUIDSignDialog(int channel, const GpgKeyPtr& key, const QString& uid, QWidget* parent) : GeneralDialog(typeid(KeyUIDSignDialog).name(), parent), current_gpg_context_channel_(channel), m_uid_(uid), m_key_(key) { - assert(m_key_.IsGood()); + assert(m_key_ != nullptr); + const auto key_id = m_key_->ID(); - const auto key_id = m_key_.ID(); m_key_list_ = new KeyList( channel, KeyMenuAbility::kCOLUMN_FILTER | KeyMenuAbility::kSEARCH_BAR, GpgKeyTableColumn::kNAME | GpgKeyTableColumn::kEMAIL_ADDRESS | @@ -51,10 +50,11 @@ KeyUIDSignDialog::KeyUIDSignDialog(int channel, const GpgKey& key, this); m_key_list_->AddListGroupTab( tr("Signers"), "signers", GpgKeyTableDisplayMode::kPRIVATE_KEY, - [key_id](const GpgKey& key) -> bool { - return !(key.IsDisabled() || !key.IsHasCertCap() || - !key.IsHasMasterKey() || key.IsExpired() || key.IsRevoked() || - key_id == key.ID()); + [key_id](const GpgAbstractKey* key) -> bool { + if (key->KeyType() != GpgAbstractKeyType::kGPG_KEY) return false; + return !(key->IsDisabled() || !key->IsHasCertCap() || + !dynamic_cast(key)->IsHasMasterKey() || + key->IsExpired() || key->IsRevoked() || key_id == key->ID()); }); m_key_list_->SlotRefresh(); @@ -103,13 +103,11 @@ KeyUIDSignDialog::KeyUIDSignDialog(int channel, const GpgKey& key, &UISignalStation::SignalKeyDatabaseRefresh); } -void KeyUIDSignDialog::slot_sign_key(bool clicked) { +void KeyUIDSignDialog::slot_sign_key(bool) { // Set Signers - auto key_ids = m_key_list_->GetChecked(); - auto keys = - GpgKeyGetter::GetInstance(current_gpg_context_channel_).GetKeys(key_ids); + auto keys = m_key_list_->GetSelectedKeys(); assert(std::all_of(keys.begin(), keys.end(), - [](const auto& key) { return key.IsGood(); })); + [](const auto& key) { return key->IsGood(); })); auto expires = std::make_unique(expires_edit_->dateTime()); diff --git a/src/ui/dialog/keypair_details/KeyUIDSignDialog.h b/src/ui/dialog/keypair_details/KeyUIDSignDialog.h index e40529fd..317cffdf 100644 --- a/src/ui/dialog/keypair_details/KeyUIDSignDialog.h +++ b/src/ui/dialog/keypair_details/KeyUIDSignDialog.h @@ -45,8 +45,8 @@ class KeyUIDSignDialog : public GeneralDialog { * @param uid * @param parent */ - explicit KeyUIDSignDialog(int channel, const GpgKey& key, const QString& uid, - QWidget* parent = nullptr); + explicit KeyUIDSignDialog(int channel, const GpgKeyPtr& key, + const QString& uid, QWidget* parent = nullptr); signals: /** @@ -63,7 +63,7 @@ class KeyUIDSignDialog : public GeneralDialog { QCheckBox* non_expire_check_; ///< QString m_uid_; ///< - const GpgKey& m_key_; ///< + const GpgKeyPtr& m_key_; ///< private slots: /** diff --git a/src/ui/function/SetOwnerTrustLevel.cpp b/src/ui/function/SetOwnerTrustLevel.cpp index e99c3fa0..ed034250 100644 --- a/src/ui/function/SetOwnerTrustLevel.cpp +++ b/src/ui/function/SetOwnerTrustLevel.cpp @@ -28,8 +28,6 @@ #include "SetOwnerTrustLevel.h" -#include "core/GpgModel.h" -#include "core/function/gpg/GpgKeyGetter.h" #include "core/function/gpg/GpgKeyManager.h" #include "ui/UISignalStation.h" @@ -37,13 +35,8 @@ namespace GpgFrontend::UI { SetOwnerTrustLevel::SetOwnerTrustLevel(QWidget* parent) : QWidget(parent) {} -auto SetOwnerTrustLevel::Exec(int channel, const QString& key_id) -> bool { - if (key_id.isEmpty()) { - return false; - } - - auto key = GpgKeyGetter::GetInstance(channel).GetKey(key_id); - assert(key.IsGood()); +auto SetOwnerTrustLevel::Exec(int channel, const GpgKeyPtr& key) -> bool { + assert(key->IsGood()); QStringList items; @@ -52,7 +45,7 @@ auto SetOwnerTrustLevel::Exec(int channel, const QString& key_id) -> bool { bool ok; QString item = QInputDialog::getItem(this, tr("Modify Owner Trust Level"), tr("Trust for the Key Pair:"), items, - key.OwnerTrustLevel(), false, &ok); + key->OwnerTrustLevel(), false, &ok); if (ok && !item.isEmpty()) { int trust_level = 0; // Unknown Level diff --git a/src/ui/function/SetOwnerTrustLevel.h b/src/ui/function/SetOwnerTrustLevel.h index ee2e98c8..00309f4d 100644 --- a/src/ui/function/SetOwnerTrustLevel.h +++ b/src/ui/function/SetOwnerTrustLevel.h @@ -29,6 +29,7 @@ #pragma once #include "GpgFrontendUI.h" +#include "core/typedef/GpgTypedef.h" namespace GpgFrontend::UI { @@ -49,7 +50,7 @@ class SetOwnerTrustLevel : public QWidget { * @return true * @return false */ - auto Exec(int channel, const QString& key_id) -> bool; + auto Exec(int channel, const GpgKeyPtr& key) -> bool; }; } // namespace GpgFrontend::UI \ No newline at end of file diff --git a/src/ui/main_window/KeyMgmt.cpp b/src/ui/main_window/KeyMgmt.cpp index 59e7a658..cd5a9f05 100644 --- a/src/ui/main_window/KeyMgmt.cpp +++ b/src/ui/main_window/KeyMgmt.cpp @@ -30,7 +30,6 @@ #include "core/function/GlobalSettingStation.h" #include "core/function/KeyPackageOperator.h" -#include "core/function/gpg/GpgKeyGetter.h" #include "core/function/gpg/GpgKeyImportExporter.h" #include "core/function/gpg/GpgKeyOpera.h" #include "core/model/GpgImportInformation.h" @@ -43,7 +42,6 @@ #include "ui/dialog/import_export/KeyImportDetailDialog.h" #include "ui/dialog/key_generate/KeyGenerateDialog.h" #include "ui/dialog/key_generate/SubkeyGenerateDialog.h" -#include "ui/dialog/keypair_details/KeyDetailsDialog.h" #include "ui/function/GpgOperaHelper.h" #include "ui/main_window/MainWindow.h" #include "ui/widgets/KeyList.h" @@ -62,25 +60,28 @@ KeyMgmt::KeyMgmt(QWidget* parent) key_list_->AddListGroupTab( tr("Only Public Key"), "only_public_key", - GpgKeyTableDisplayMode::kPUBLIC_KEY, [](const GpgKey& key) -> bool { - return !key.IsPrivateKey() && - !(key.IsRevoked() || key.IsDisabled() || key.IsExpired()); + GpgKeyTableDisplayMode::kPUBLIC_KEY, + [](const GpgAbstractKey* key) -> bool { + return !key->IsPrivateKey() && + !(key->IsRevoked() || key->IsDisabled() || key->IsExpired()); }); key_list_->AddListGroupTab( tr("Has Private Key"), "has_private_key", - GpgKeyTableDisplayMode::kPRIVATE_KEY, [](const GpgKey& key) -> bool { - return key.IsPrivateKey() && - !(key.IsRevoked() || key.IsDisabled() || key.IsExpired()); + GpgKeyTableDisplayMode::kPRIVATE_KEY, + [](const GpgAbstractKey* key) -> bool { + return key->IsPrivateKey() && + !(key->IsRevoked() || key->IsDisabled() || key->IsExpired()); }); key_list_->AddListGroupTab( tr("No Primary Key"), "no_primary_key", GpgKeyTableDisplayMode::kPUBLIC_KEY | GpgKeyTableDisplayMode::kPRIVATE_KEY, - [](const GpgKey& key) -> bool { - return !key.IsHasMasterKey() && - !(key.IsRevoked() || key.IsDisabled() || key.IsExpired()); + [](const GpgAbstractKey* key) -> bool { + if (key->KeyType() != GpgAbstractKeyType::kGPG_KEY) return false; + return !dynamic_cast(key)->IsHasMasterKey() && + !(key->IsRevoked() || key->IsDisabled() || key->IsExpired()); }); key_list_->AddListGroupTab( @@ -88,14 +89,20 @@ KeyMgmt::KeyMgmt(QWidget* parent) GpgKeyTableDisplayMode::kPUBLIC_KEY | GpgKeyTableDisplayMode::kPRIVATE_KEY, - [](const GpgKey& key) -> bool { return key.IsRevoked(); }); + [](const GpgAbstractKey* key) -> bool { return key->IsRevoked(); }); key_list_->AddListGroupTab( tr("Expired"), "expired", GpgKeyTableDisplayMode::kPUBLIC_KEY | GpgKeyTableDisplayMode::kPRIVATE_KEY, - [](const GpgKey& key) -> bool { return key.IsExpired(); }); + [](const GpgAbstractKey* key) -> bool { return key->IsExpired(); }); + + key_list_->AddListGroupTab( + tr("Disabled"), "disabled", + GpgKeyTableDisplayMode::kPUBLIC_KEY | + GpgKeyTableDisplayMode::kPRIVATE_KEY, + [](const GpgAbstractKey* key) -> bool { return key->IsDisabled(); }); setCentralWidget(key_list_); @@ -248,12 +255,11 @@ void KeyMgmt::create_actions() { set_owner_trust_of_key_act_->setToolTip(tr("Set Owner Trust Level")); set_owner_trust_of_key_act_->setData(QVariant("set_owner_trust_level")); connect(set_owner_trust_of_key_act_, &QAction::triggered, this, [this]() { - auto keys_selected = key_list_->GetSelected(); - if (keys_selected.empty()) return; + auto key = key_list_->GetSelectedGpgKey(); + if (key == nullptr) return; auto* function = new SetOwnerTrustLevel(this); - function->Exec(key_list_->GetCurrentGpgContextChannel(), - keys_selected.front()); + function->Exec(key_list_->GetCurrentGpgContextChannel(), key); function->deleteLater(); }); } @@ -313,29 +319,22 @@ void KeyMgmt::create_tool_bars() { } void KeyMgmt::SlotDeleteSelectedKeys() { - delete_keys_with_warning(key_list_->GetSelected()); + delete_keys_with_warning(key_list_->GetSelectedKeys()); } void KeyMgmt::SlotDeleteCheckedKeys() { - delete_keys_with_warning(key_list_->GetChecked()); + delete_keys_with_warning(key_list_->GetCheckedKeys()); } -void KeyMgmt::delete_keys_with_warning(KeyIdArgsList uid_list) { - /** - * TODO: Different Messages for private/public key, check if - * more than one selected... compare to seahorse "delete-dialog" - */ +void KeyMgmt::delete_keys_with_warning(const GpgAbstractKeyPtrList& keys) { + if (keys.empty()) return; - if (uid_list.empty()) return; QString keynames; - for (const auto& key_id : uid_list) { - auto key = - GpgKeyGetter::GetInstance(key_list_->GetCurrentGpgContextChannel()) - .GetKey(key_id); - if (!key.IsGood()) continue; - keynames.append(key.Name()); + for (const auto& key : keys) { + if (!key->IsGood()) continue; + keynames.append(key->Name()); keynames.append(" <"); - keynames.append(key.Email()); + keynames.append(key->Email()); keynames.append(">
"); } @@ -348,96 +347,79 @@ void KeyMgmt::delete_keys_with_warning(KeyIdArgsList uid_list) { if (ret == QMessageBox::Yes) { GpgKeyOpera::GetInstance(key_list_->GetCurrentGpgContextChannel()) - .DeleteKeys(std::move(uid_list)); + .DeleteKeys(keys); emit SignalKeyStatusUpdated(); } } void KeyMgmt::SlotShowKeyDetails() { - auto [succ, key] = key_list_->GetSelectedGpgKey(); - if (!succ) return; + auto keys = key_list_->GetSelectedKeys(); + if (keys.isEmpty()) return; - new KeyDetailsDialog(key_list_->GetCurrentGpgContextChannel(), key, this); + CommonUtils::OpenDetailsDialogByKey( + this, key_list_->GetCurrentGpgContextChannel(), keys.front()); } void KeyMgmt::SlotExportKeyToKeyPackage() { - auto keys_checked = key_list_->GetChecked(); - if (keys_checked.empty()) { + auto keys = key_list_->GetCheckedKeys(); + if (keys.empty()) { QMessageBox::critical( this, tr("Forbidden"), tr("Please check some keys before doing this operation.")); return; } + auto* dialog = new ExportKeyPackageDialog( - key_list_->GetCurrentGpgContextChannel(), std::move(keys_checked), this); + key_list_->GetCurrentGpgContextChannel(), keys, this); dialog->exec(); emit SignalStatusBarChanged(tr("key(s) exported")); } void KeyMgmt::SlotExportKeyToClipboard() { - auto keys_checked = key_list_->GetChecked(); - if (keys_checked.empty()) { + auto keys = key_list_->GetCheckedKeys(); + if (keys.empty()) { QMessageBox::critical( this, tr("Forbidden"), tr("Please check some keys before doing this operation.")); return; } - if (keys_checked.size() == 1) { - auto key = - GpgKeyGetter::GetInstance(key_list_->GetCurrentGpgContextChannel()) - .GetKey(keys_checked.front()); - assert(key.IsGood()); - - auto [err, gf_buffer] = GpgKeyImportExporter::GetInstance( - key_list_->GetCurrentGpgContextChannel()) - .ExportKey(key, false, true, false); - if (CheckGpgError(err) != GPG_ERR_NO_ERROR) { - CommonUtils::RaiseMessageBox(this, err); - return; - } - QApplication::clipboard()->setText(gf_buffer.ConvertToQByteArray()); - } else { - auto keys = - GpgKeyGetter::GetInstance(key_list_->GetCurrentGpgContextChannel()) - .GetKeys(keys_checked); - assert(std::all_of(keys.begin(), keys.end(), - [](const auto& key) { return key.IsGood(); })); - - GpgOperaHelper::WaitForOpera( - this, tr("Exporting"), [=](const OperaWaitingHd& op_hd) { - GpgKeyImportExporter::GetInstance( - key_list_->GetCurrentGpgContextChannel()) - .ExportKeys( - keys, false, true, false, false, - [=](GpgError err, const DataObjectPtr& data_obj) { - // stop waiting - op_hd(); - - if (CheckGpgError(err) == GPG_ERR_USER_1) { - QMessageBox::critical(this, tr("Error"), - tr("Unknown error occurred")); - return; - } - - if (CheckGpgError(err) != GPG_ERR_NO_ERROR) { - CommonUtils::RaiseMessageBox(this, err); - return; - } - - if (data_obj == nullptr || !data_obj->Check()) { - FLOG_W("data object checking failed"); - QMessageBox::critical(this, tr("Error"), - tr("Unknown error occurred")); - return; - } - - auto gf_buffer = ExtractParams(data_obj, 0); - QApplication::clipboard()->setText( - gf_buffer.ConvertToQByteArray()); - }); - }); - } + assert(std::all_of(keys.begin(), keys.end(), + [](const auto& key) { return key->IsGood(); })); + + GpgOperaHelper::WaitForOpera( + this, tr("Exporting"), [=](const OperaWaitingHd& op_hd) { + GpgKeyImportExporter::GetInstance( + key_list_->GetCurrentGpgContextChannel()) + .ExportKeys( + keys, false, true, false, false, + [=](GpgError err, const DataObjectPtr& data_obj) { + // stop waiting + op_hd(); + + if (CheckGpgError(err) == GPG_ERR_USER_1) { + QMessageBox::critical(this, tr("Error"), + tr("Unknown error occurred")); + return; + } + + if (CheckGpgError(err) != GPG_ERR_NO_ERROR) { + CommonUtils::RaiseMessageBox(this, err); + return; + } + + if (data_obj == nullptr || !data_obj->Check()) { + FLOG_W("data object checking failed"); + QMessageBox::critical(this, tr("Error"), + tr("Unknown error occurred")); + return; + } + + auto gf_buffer = ExtractParams(data_obj, 0); + QApplication::clipboard()->setText( + gf_buffer.ConvertToQByteArray()); + }); + }); } void KeyMgmt::SlotGenerateKeyDialog() { @@ -447,43 +429,40 @@ void KeyMgmt::SlotGenerateKeyDialog() { } void KeyMgmt::SlotGenerateSubKey() { - auto [succ, key] = key_list_->GetSelectedGpgKey(); - if (!succ) return; + auto key = key_list_->GetSelectedGpgKey(); + if (key == nullptr) return; - if (!key.IsPrivateKey()) { + if (!key->IsPrivateKey()) { QMessageBox::critical(this, tr("Invalid Operation"), tr("If a key pair does not have a private key then " "it will not be able to generate sub-keys.")); return; } - (new SubkeyGenerateDialog(key_list_->GetCurrentGpgContextChannel(), key.ID(), + (new SubkeyGenerateDialog(key_list_->GetCurrentGpgContextChannel(), key, this)) ->exec(); this->raise(); } void KeyMgmt::SlotExportAsOpenSSHFormat() { - auto keys_checked = key_list_->GetChecked(); - if (keys_checked.empty()) { + auto keys = key_list_->GetCheckedKeys(); + if (keys.empty()) { QMessageBox::critical( this, tr("Forbidden"), tr("Please check a key before performing this operation.")); return; } - if (keys_checked.size() > 1) { + assert(std::all_of(keys.begin(), keys.end(), + [](const auto& key) { return key->IsGood(); })); + + if (keys.size() > 1) { QMessageBox::critical(this, tr("Forbidden"), tr("This operation accepts just a single key.")); return; } - auto keys = - GpgKeyGetter::GetInstance(key_list_->GetCurrentGpgContextChannel()) - .GetKeys(keys_checked); - assert(std::all_of(keys.begin(), keys.end(), - [](const auto& key) { return key.IsGood(); })); - GpgOperaHelper::WaitForOpera( this, tr("Exporting"), [this, keys](const OperaWaitingHd& op_hd) { GpgKeyImportExporter::GetInstance( diff --git a/src/ui/main_window/KeyMgmt.h b/src/ui/main_window/KeyMgmt.h index c0c004af..b25cfaaa 100644 --- a/src/ui/main_window/KeyMgmt.h +++ b/src/ui/main_window/KeyMgmt.h @@ -121,31 +121,6 @@ class KeyMgmt : public GeneralMainWindow { void SignalKeyStatusUpdated(); private: - /** - * @brief Create a menus object - * - */ - void create_menus(); - - /** - * @brief Create a actions object - * - */ - void create_actions(); - - /** - * @brief Create a tool bars object - * - */ - void create_tool_bars(); - - /** - * @brief - * - * @param uidList - */ - void delete_keys_with_warning(KeyIdArgsList uid_list); - KeyList* key_list_; ///< QMenu* file_menu_{}; ///< QMenu* key_menu_{}; ///< @@ -169,6 +144,31 @@ class KeyMgmt : public GeneralMainWindow { QAction* close_act_{}; ///< QAction* show_key_details_act_{}; ///< QAction* set_owner_trust_of_key_act_{}; + + /** + * @brief Create a menus object + * + */ + void create_menus(); + + /** + * @brief Create a actions object + * + */ + void create_actions(); + + /** + * @brief Create a tool bars object + * + */ + void create_tool_bars(); + + /** + * @brief + * + * @param uidList + */ + void delete_keys_with_warning(const GpgAbstractKeyPtrList& keys); }; } // namespace GpgFrontend::UI diff --git a/src/ui/main_window/MainWindow.cpp b/src/ui/main_window/MainWindow.cpp index 698cd535..5ebfbb00 100644 --- a/src/ui/main_window/MainWindow.cpp +++ b/src/ui/main_window/MainWindow.cpp @@ -60,7 +60,8 @@ void MainWindow::Init() noexcept { kGpgFrontendDefaultChannel, KeyMenuAbility::kREFRESH | KeyMenuAbility::kCHECK_ALL | KeyMenuAbility::kUNCHECK_ALL | KeyMenuAbility::kCOLUMN_FILTER | - KeyMenuAbility::kSEARCH_BAR | KeyMenuAbility::kKEY_DATABASE, + KeyMenuAbility::kSEARCH_BAR | KeyMenuAbility::kKEY_DATABASE | + KeyMenuAbility::kKEY_GROUP, GpgKeyTableColumn::kTYPE | GpgKeyTableColumn::kNAME | GpgKeyTableColumn::kKEY_ID | GpgKeyTableColumn::kEMAIL_ADDRESS | GpgKeyTableColumn::kUSAGE | GpgKeyTableColumn::kOWNER_TRUST | @@ -138,6 +139,8 @@ void MainWindow::Init() noexcept { // recover unsaved page from cache if it exists recover_editor_unsaved_pages_from_cache(); + slot_update_operations_menu_by_checked_keys(); + // check if need to open wizard window if (GetSettings().value("wizard/show_wizard", true).toBool()) { slot_start_wizard(); diff --git a/src/ui/main_window/MainWindow.h b/src/ui/main_window/MainWindow.h index 58aa406d..6eb4da65 100644 --- a/src/ui/main_window/MainWindow.h +++ b/src/ui/main_window/MainWindow.h @@ -522,6 +522,13 @@ class MainWindow : public GeneralMainWindow { void slot_gpg_opera_buffer_show_helper( const QContainer& results); + /** + * @brief + * + * @param results + */ + void slot_update_operations_menu_by_checked_keys(); + private: /** * @details Create actions for the main-menu and the context-menu of the @@ -625,9 +632,9 @@ class MainWindow : public GeneralMainWindow { * @return GpgKeyList */ auto check_keys_helper( - const KeyIdArgsList& key_ids, - const std::function& capability_check, - const QString& capability_err_string) -> GpgKeyList; + const GpgAbstractKeyPtrList& keys, + const std::function& capability_check, + const QString& capability_err_string) -> GpgAbstractKeyPtrList; /** * @brief diff --git a/src/ui/main_window/MainWindowGpgOperaFunction.cpp b/src/ui/main_window/MainWindowGpgOperaFunction.cpp index dc65fd1c..925950eb 100644 --- a/src/ui/main_window/MainWindowGpgOperaFunction.cpp +++ b/src/ui/main_window/MainWindowGpgOperaFunction.cpp @@ -27,8 +27,6 @@ */ #include "MainWindow.h" -#include "core/function/GlobalSettingStation.h" -#include "core/function/gpg/GpgKeyGetter.h" #include "core/utils/GpgUtils.h" #include "core/utils/IOUtils.h" #include "ui/UserInterfaceUtils.h" @@ -42,10 +40,10 @@ namespace GpgFrontend::UI { auto MainWindow::encrypt_operation_key_validate( const QSharedPointer& contexts) -> bool { - auto key_ids = m_key_list_->GetChecked(); + auto keys = m_key_list_->GetCheckedKeys(); // symmetric encryption - if (key_ids.isEmpty()) { + if (keys.isEmpty()) { auto ret = QMessageBox::information( this, tr("Symmetric Encryption"), tr("No Key Selected. Do you want to encrypt with a " @@ -56,7 +54,7 @@ auto MainWindow::encrypt_operation_key_validate( contexts->keys = {}; } else { contexts->keys = check_keys_helper( - key_ids, [](const GpgKey& key) { return key.IsHasActualEncrCap(); }, + keys, [](const GpgAbstractKeyPtr& key) { return key->IsHasEncrCap(); }, tr("The selected keypair cannot be used for encryption.")); if (contexts->keys.empty()) return false; } @@ -75,12 +73,9 @@ auto MainWindow::sign_operation_key_validate( // return when canceled if (!signers_picker->GetStatus()) return false; - auto signer_key_ids = signers_picker->GetCheckedSigners(); - auto signer_keys = - GpgKeyGetter::GetInstance(m_key_list_->GetCurrentGpgContextChannel()) - .GetKeys(signer_key_ids); + auto signer_keys = signers_picker->GetCheckedSigners(); assert(std::all_of(signer_keys.begin(), signer_keys.end(), - [](const auto& key) { return key.IsGood(); })); + [](const auto& key) { return key->IsGood(); })); contexts->singer_keys = signer_keys; @@ -150,21 +145,18 @@ auto MainWindow::check_write_file_paths_helper(const QStringList& o_paths) } auto MainWindow::check_keys_helper( - const KeyIdArgsList& key_ids, - const std::function& capability_check, - const QString& capability_err_string) -> GpgKeyList { - if (key_ids.empty()) { + const GpgAbstractKeyPtrList& keys, + const std::function& capability_check, + const QString& capability_err_string) -> GpgAbstractKeyPtrList { + if (keys.isEmpty()) { QMessageBox::critical( this, tr("No Key Checked"), tr("Please check the key in the key toolbox on the right.")); return {}; } - auto keys = - GpgKeyGetter::GetInstance(m_key_list_->GetCurrentGpgContextChannel()) - .GetKeys(key_ids); assert(std::all_of(keys.begin(), keys.end(), - [](const auto& key) { return key.IsGood(); })); + [](const auto& key) { return key->IsGood(); })); // check key abilities for (const auto& key : keys) { @@ -172,7 +164,7 @@ auto MainWindow::check_keys_helper( QMessageBox::critical(nullptr, tr("Invalid KeyPair"), capability_err_string + "

" + tr("For example the Following Key:") + - "
" + key.UIDs().front().GetUID()); + "
" + key->Email()); return {}; } } @@ -202,9 +194,10 @@ void MainWindow::SlotSign() { auto contexts = QSharedPointer::create(); contexts->ascii = true; - auto key_ids = m_key_list_->GetChecked(); + auto keys = m_key_list_->GetCheckedKeys(); + contexts->keys = check_keys_helper( - key_ids, [](const GpgKey& key) { return key.IsHasActualSignCap(); }, + keys, [](const GpgAbstractKeyPtr& key) { return key->IsHasSignCap(); }, tr("The selected key contains a key that does not actually have a " "sign usage.")); if (contexts->keys.empty()) return; @@ -255,9 +248,10 @@ void MainWindow::SlotEncryptSign() { auto contexts = QSharedPointer::create(); contexts->ascii = true; - auto key_ids = m_key_list_->GetChecked(); + auto keys = m_key_list_->GetCheckedKeys(); + contexts->keys = check_keys_helper( - key_ids, [](const GpgKey& key) { return key.IsHasActualEncrCap(); }, + keys, [](const GpgAbstractKeyPtr& key) { return key->IsHasEncrCap(); }, tr("The selected keypair cannot be used for encryption.")); if (contexts->keys.empty()) return; @@ -363,9 +357,10 @@ void MainWindow::SlotFileSign(const QStringList& paths, bool ascii) { contexts->ascii = ascii; - auto key_ids = m_key_list_->GetChecked(); + auto keys = m_key_list_->GetCheckedKeys(); + contexts->keys = check_keys_helper( - key_ids, [](const GpgKey& key) { return key.IsHasActualSignCap(); }, + keys, [](const GpgAbstractKeyPtr& key) { return key->IsHasSignCap(); }, tr("The selected key contains a key that does not actually have a " "sign usage.")); if (contexts->keys.empty()) return; @@ -442,9 +437,9 @@ void MainWindow::SlotFileEncryptSign(const QStringList& paths, bool ascii) { auto contexts = QSharedPointer::create(); contexts->ascii = ascii; - auto key_ids = m_key_list_->GetChecked(); + auto keys = m_key_list_->GetCheckedKeys(); contexts->keys = check_keys_helper( - key_ids, [](const GpgKey& key) { return key.IsHasActualEncrCap(); }, + keys, [](const GpgAbstractKeyPtr& key) { return key->IsHasEncrCap(); }, tr("The selected keypair cannot be used for encryption.")); if (contexts->keys.empty()) return; diff --git a/src/ui/main_window/MainWindowSlotFunction.cpp b/src/ui/main_window/MainWindowSlotFunction.cpp index fb4f9e73..b19c15e8 100644 --- a/src/ui/main_window/MainWindowSlotFunction.cpp +++ b/src/ui/main_window/MainWindowSlotFunction.cpp @@ -27,7 +27,6 @@ */ #include "MainWindow.h" -#include "core/function/gpg/GpgKeyGetter.h" #include "core/function/gpg/GpgKeyImportExporter.h" #include "core/function/result_analyse/GpgDecryptResultAnalyse.h" #include "core/function/result_analyse/GpgEncryptResultAnalyse.h" @@ -45,7 +44,6 @@ #include "ui/dialog/SignersPicker.h" #include "ui/dialog/help/AboutDialog.h" #include "ui/dialog/import_export/KeyUploadDialog.h" -#include "ui/dialog/keypair_details/KeyDetailsDialog.h" #include "ui/function/GpgOperaHelper.h" #include "ui/function/SetOwnerTrustLevel.h" #include "ui/struct/GpgOperaResult.h" @@ -71,25 +69,12 @@ void MainWindow::slot_find() { * Append the selected (not checked!) Key(s) To Textedit */ void MainWindow::slot_append_selected_keys() { - auto key_ids = m_key_list_->GetSelected(); - - if (key_ids.empty()) { - FLOG_W("no key is selected to export"); - return; - } - - auto key = - GpgKeyGetter::GetInstance(m_key_list_->GetCurrentGpgContextChannel()) - .GetKey(key_ids.front()); - if (!key.IsGood()) { - LOG_W() << "selected key for exporting is invalid, key id: " - << key_ids.front(); - return; - } + auto keys = m_key_list_->GetSelectedKeys(); + if (keys.empty()) return; auto [err, gf_buffer] = GpgKeyImportExporter::GetInstance( m_key_list_->GetCurrentGpgContextChannel()) - .ExportKey(key, false, true, false); + .ExportKey(keys.front(), false, true, false); if (CheckGpgError(err) != GPG_ERR_NO_ERROR) { CommonUtils::RaiseMessageBox(this, err); return; @@ -99,123 +84,121 @@ void MainWindow::slot_append_selected_keys() { } void MainWindow::slot_append_keys_create_datetime() { - auto [succ, key] = m_key_list_->GetSelectedGpgKey(); - if (!succ) return; + auto key = m_key_list_->GetSelectedKey(); + if (key == nullptr) return; auto create_datetime_format_str_local = - QLocale().toString(key.CreationTime()) + " (" + tr("Localize") + ") " + + QLocale().toString(key->CreationTime()) + " (" + tr("Localize") + ") " + "\n"; auto create_datetime_format_str = - QLocale().toString(key.CreationTime().toUTC()) + " (" + tr("UTC") + ") " + - "\n "; + QLocale().toString(key->CreationTime().toUTC()) + " (" + tr("UTC") + + ") " + "\n "; edit_->SlotAppendText2CurTextPage(create_datetime_format_str_local + create_datetime_format_str); } void MainWindow::slot_append_keys_expire_datetime() { - auto [succ, key] = m_key_list_->GetSelectedGpgKey(); - if (!succ) return; + auto key = m_key_list_->GetSelectedKey(); + if (key == nullptr) return; auto expire_datetime_format_str_local = - QLocale().toString(key.ExpirationTime()) + " (" + tr("Local Time") + + QLocale().toString(key->ExpirationTime()) + " (" + tr("Local Time") + ") " + "\n"; auto expire_datetime_format_str = - QLocale().toString(key.ExpirationTime().toUTC()) + " (UTC) " + "\n"; + QLocale().toString(key->ExpirationTime().toUTC()) + " (UTC) " + "\n"; edit_->SlotAppendText2CurTextPage(expire_datetime_format_str_local + expire_datetime_format_str); } void MainWindow::slot_append_keys_fingerprint() { - auto [succ, key] = m_key_list_->GetSelectedGpgKey(); - if (!succ) return; + auto key = m_key_list_->GetSelectedKey(); + if (key == nullptr) return; - auto fingerprint_format_str = BeautifyFingerprint(key.Fingerprint()) + "\n"; + auto fingerprint_format_str = BeautifyFingerprint(key->Fingerprint()) + "\n"; edit_->SlotAppendText2CurTextPage(fingerprint_format_str); } void MainWindow::slot_copy_mail_address_to_clipboard() { - auto [succ, key] = m_key_list_->GetSelectedGpgKey(); - if (!succ) return; + auto key = m_key_list_->GetSelectedKey(); + if (key == nullptr) return; QClipboard* cb = QApplication::clipboard(); - cb->setText(key.Email()); + cb->setText(key->Email()); } void MainWindow::slot_copy_default_uid_to_clipboard() { - auto [succ, key] = m_key_list_->GetSelectedGpgKey(); - if (!succ) return; + auto key = m_key_list_->GetSelectedKey(); + if (key == nullptr || key->KeyType() != GpgAbstractKeyType::kGPG_KEY) return; QClipboard* cb = QApplication::clipboard(); - cb->setText(key.UIDs().front().GetUID()); + cb->setText(qSharedPointerDynamicCast(key)->UIDs().front().GetUID()); } void MainWindow::slot_copy_key_id_to_clipboard() { - auto [succ, key] = m_key_list_->GetSelectedGpgKey(); - if (!succ) return; + auto key = m_key_list_->GetSelectedKey(); + if (key == nullptr) return; QClipboard* cb = QApplication::clipboard(); - cb->setText(key.ID()); + cb->setText(key->ID()); } void MainWindow::slot_show_key_details() { - auto [succ, key] = m_key_list_->GetSelectedGpgKey(); - if (!succ) return; + auto keys = m_key_list_->GetSelectedKeys(); + if (keys.isEmpty()) return; - new KeyDetailsDialog(m_key_list_->GetCurrentGpgContextChannel(), key, this); + CommonUtils::OpenDetailsDialogByKey( + this, m_key_list_->GetCurrentGpgContextChannel(), keys.front()); } void MainWindow::slot_add_key_2_favorite() { - auto [succ, key] = m_key_list_->GetSelectedGpgKey(); - if (!succ) return; + auto key = m_key_list_->GetSelectedKey(); + if (key == nullptr) return; auto key_db_name = GetGpgKeyDatabaseName(m_key_list_->GetCurrentGpgContextChannel()); - LOG_D() << "add key" << key.ID() << "to favorite at key db" << key_db_name; + LOG_D() << "add key" << key->ID() << "to favorite at key db" << key_db_name; CommonUtils::GetInstance()->AddKey2Favorite(key_db_name, key); emit SignalUIRefresh(); } void MainWindow::slot_remove_key_from_favorite() { - auto key_ids = m_key_list_->GetSelected(); - if (key_ids.empty()) return; - - auto key = - GpgKeyGetter::GetInstance(m_key_list_->GetCurrentGpgContextChannel()) - .GetKey(key_ids.front()); - assert(key.IsGood()); + auto keys = m_key_list_->GetSelectedKeys(); + if (keys.empty()) return; auto key_db_name = GetGpgKeyDatabaseName(m_key_list_->GetCurrentGpgContextChannel()); - CommonUtils::GetInstance()->RemoveKeyFromFavorite(key_db_name, key); + CommonUtils::GetInstance()->RemoveKeyFromFavorite(key_db_name, keys.front()); emit SignalUIRefresh(); } void MainWindow::refresh_keys_from_key_server() { - auto key_ids = m_key_list_->GetSelected(); - if (key_ids.empty()) return; - CommonUtils::GetInstance()->ImportKeyFromKeyServer( - m_key_list_->GetCurrentGpgContextChannel(), key_ids); + auto keys = m_key_list_->GetSelectedGpgKeys(); + if (keys.empty()) return; + CommonUtils::GetInstance()->ImportGpgKeyFromKeyServer( + m_key_list_->GetCurrentGpgContextChannel(), keys); } void MainWindow::slot_set_owner_trust_level_of_key() { - auto key_ids = m_key_list_->GetSelected(); - if (key_ids.empty()) return; + auto keys = m_key_list_->GetSelectedGpgKeys(); + if (keys.empty()) return; auto* function = new SetOwnerTrustLevel(this); - function->Exec(m_key_list_->GetCurrentGpgContextChannel(), key_ids.front()); + function->Exec(m_key_list_->GetCurrentGpgContextChannel(), keys.front()); function->deleteLater(); } void MainWindow::upload_key_to_server() { - auto key_ids = m_key_list_->GetSelected(); + auto keys = m_key_list_->GetSelectedKeys(); + if (keys.empty()) return; + auto* dialog = new KeyUploadDialog(m_key_list_->GetCurrentGpgContextChannel(), - key_ids, this); + keys, this); dialog->show(); dialog->SlotUpload(); } @@ -640,25 +623,28 @@ void MainWindow::decrypt_email_by_eml_data_result_helper( void MainWindow::SlotEncryptEML() { if (edit_->TabCount() == 0 || edit_->CurEMailPage() == nullptr) return; - auto checked_keys = m_key_list_->GetCheckedKeys(); + auto keys = m_key_list_->GetCheckedKeys(); - if (checked_keys.isEmpty()) { + if (keys.isEmpty()) { QMessageBox::warning(this, tr("No Key Selected"), tr("Please select a key for encrypt the EML.")); return; } auto buffer = edit_->CurPlainText().toUtf8(); + auto key_ids = + ConvertKey2GpgKeyIdList(m_key_list_->GetCurrentGpgContextChannel(), keys); + GpgOperaHelper::WaitForOpera( this, tr("Encrypting"), - [this, buffer, checked_keys](const OperaWaitingHd& hd) { + [this, buffer, key_ids](const OperaWaitingHd& hd) { Module::TriggerEvent( "EMAIL_ENCRYPT_EML_DATA", { {"body_data", QString::fromLatin1(buffer.toBase64())}, {"channel", QString::number(m_key_list_->GetCurrentGpgContextChannel())}, - {"encrypt_keys", checked_keys.join(';')}, + {"encrypt_keys", key_ids.join(';')}, }, [=](Module::EventIdentifier i, Module::Event::ListenerIdentifier ei, @@ -700,32 +686,33 @@ void MainWindow::SlotEncryptEML() { void MainWindow::SlotSignEML() { if (edit_->TabCount() == 0 || edit_->CurEMailPage() == nullptr) return; - auto checked_keys = m_key_list_->GetCheckedKeys(); + auto keys = m_key_list_->GetCheckedKeys(); - if (checked_keys.isEmpty()) { + if (keys.isEmpty()) { QMessageBox::warning(this, tr("No Key Selected"), tr("Please select a key for signing the EML.")); return; } - if (checked_keys.size() > 1) { + if (keys.size() > 1) { QMessageBox::warning(this, tr("Multiple Keys Selected"), tr("Please select only one key to sign the EML.")); return; } auto buffer = edit_->CurPlainText().toUtf8(); + auto key_ids = + ConvertKey2GpgKeyIdList(m_key_list_->GetCurrentGpgContextChannel(), keys); GpgOperaHelper::WaitForOpera( - this, tr("Signing"), - [this, buffer, checked_keys](const OperaWaitingHd& hd) { + this, tr("Signing"), [this, buffer, key_ids](const OperaWaitingHd& hd) { Module::TriggerEvent( "EMAIL_SIGN_EML_DATA", { {"body_data", QString::fromLatin1(buffer.toBase64())}, {"channel", QString::number(m_key_list_->GetCurrentGpgContextChannel())}, - {"sign_key", checked_keys.front()}, + {"sign_key", key_ids.front()}, }, [=](Module::EventIdentifier i, Module::Event::ListenerIdentifier ei, Module::Event::Params p) { @@ -766,9 +753,9 @@ void MainWindow::SlotSignEML() { void MainWindow::SlotEncryptSignEML() { if (edit_->TabCount() == 0 || edit_->CurEMailPage() == nullptr) return; - auto checked_keys = m_key_list_->GetCheckedKeys(); + auto keys = m_key_list_->GetCheckedKeys(); - if (checked_keys.isEmpty()) { + if (keys.isEmpty()) { QMessageBox::warning(this, tr("No Key Selected"), tr("Please select a key for encrypt the EML.")); return; @@ -783,7 +770,7 @@ void MainWindow::SlotEncryptSignEML() { // return when canceled if (!signers_picker->GetStatus()) return; - auto signer_keys = signers_picker->GetCheckedSignerKeyIds(); + auto signer_keys = signers_picker->GetCheckedSigners(); if (signer_keys.isEmpty()) { QMessageBox::warning(this, tr("No Key Selected"), @@ -798,18 +785,20 @@ void MainWindow::SlotEncryptSignEML() { } auto buffer = edit_->CurPlainText().toUtf8(); + auto key_ids = + ConvertKey2GpgKeyIdList(m_key_list_->GetCurrentGpgContextChannel(), keys); GpgOperaHelper::WaitForOpera( this, tr("Encrypting and Signing"), - [this, buffer, checked_keys, signer_keys](const OperaWaitingHd& hd) { + [this, buffer, key_ids, signer_keys](const OperaWaitingHd& hd) { Module::TriggerEvent( "EMAIL_ENCRYPT_SIGN_EML_DATA", { {"body_data", QString::fromLatin1(buffer.toBase64())}, {"channel", QString::number(m_key_list_->GetCurrentGpgContextChannel())}, - {"sign_key", signer_keys.front()}, - {"encrypt_keys", checked_keys.front()}, + {"sign_key", signer_keys.front()->ID()}, + {"encrypt_keys", key_ids.front()}, }, [=](Module::EventIdentifier i, Module::Event::ListenerIdentifier ei, Module::Event::Params p) { diff --git a/src/ui/main_window/MainWindowSlotUI.cpp b/src/ui/main_window/MainWindowSlotUI.cpp index 248e6488..51de7d23 100644 --- a/src/ui/main_window/MainWindowSlotUI.cpp +++ b/src/ui/main_window/MainWindowSlotUI.cpp @@ -29,7 +29,6 @@ #include "MainWindow.h" #include "core/GpgConstants.h" #include "core/function/CacheManager.h" -#include "core/function/GlobalSettingStation.h" #include "core/function/gpg/GpgAdvancedOperator.h" #include "core/model/SettingsObject.h" #include "ui/UserInterfaceUtils.h" @@ -37,6 +36,7 @@ #include "ui/dialog/settings/SettingsDialog.h" #include "ui/main_window/KeyMgmt.h" #include "ui/struct/settings_object/AppearanceSO.h" +#include "ui/widgets/KeyList.h" #include "ui/widgets/TextEdit.h" namespace GpgFrontend::UI { @@ -168,7 +168,7 @@ void MainWindow::slot_cut_pgp_header() { void MainWindow::SlotSetRestartNeeded(int mode) { this->restart_mode_ = mode; } void MainWindow::SlotUpdateCryptoMenuStatus(unsigned int type) { - MainWindow::OperationMenu::OperationType opera_type = type; + OperationMenu::OperationType opera_type = type; // refresh status to disable all verify_act_->setDisabled(true); @@ -179,22 +179,22 @@ void MainWindow::SlotUpdateCryptoMenuStatus(unsigned int type) { decrypt_verify_act_->setDisabled(true); // gnupg operations - if ((opera_type & MainWindow::OperationMenu::kVerify) != 0U) { + if ((opera_type & OperationMenu::kVerify) != 0U) { verify_act_->setDisabled(false); } - if ((opera_type & MainWindow::OperationMenu::kSign) != 0U) { + if ((opera_type & OperationMenu::kSign) != 0U) { sign_act_->setDisabled(false); } - if ((opera_type & MainWindow::OperationMenu::kEncrypt) != 0U) { + if ((opera_type & OperationMenu::kEncrypt) != 0U) { encrypt_act_->setDisabled(false); } - if ((opera_type & MainWindow::OperationMenu::kEncryptAndSign) != 0U) { + if ((opera_type & OperationMenu::kEncryptAndSign) != 0U) { encrypt_sign_act_->setDisabled(false); } - if ((opera_type & MainWindow::OperationMenu::kDecrypt) != 0U) { + if ((opera_type & OperationMenu::kDecrypt) != 0U) { decrypt_act_->setDisabled(false); } - if ((opera_type & MainWindow::OperationMenu::kDecryptAndVerify) != 0U) { + if ((opera_type & OperationMenu::kDecryptAndVerify) != 0U) { decrypt_verify_act_->setDisabled(false); } } @@ -346,4 +346,29 @@ void MainWindow::slot_restart_gpg_components(bool) { }); } +void MainWindow::slot_update_operations_menu_by_checked_keys() { + auto keys = m_key_list_->GetCheckedKeys(); + + OperationMenu::OperationType type = ~0; + + if (keys.isEmpty()) { + type &= ~(OperationMenu::kEncrypt | OperationMenu::kEncryptAndSign | + OperationMenu::kSign); + + } else { + for (const auto& key : keys) { + if (key == nullptr || key->IsDisabled()) continue; + + if (!key->IsHasEncrCap()) { + type &= ~(OperationMenu::kEncrypt | OperationMenu::kEncryptAndSign); + } + if (!key->IsHasSignCap()) { + type &= ~(OperationMenu::kSign); + } + } + } + + SlotUpdateCryptoMenuStatus(type); +} + } // namespace GpgFrontend::UI diff --git a/src/ui/main_window/MainWindowUI.cpp b/src/ui/main_window/MainWindowUI.cpp index 6598aede..26c3a8ad 100644 --- a/src/ui/main_window/MainWindowUI.cpp +++ b/src/ui/main_window/MainWindowUI.cpp @@ -570,28 +570,31 @@ void MainWindow::create_dock_windows() { tr("Default"), "default", GpgKeyTableDisplayMode::kPUBLIC_KEY | GpgKeyTableDisplayMode::kPRIVATE_KEY, - [](const GpgKey& key) -> bool { - return !(key.IsRevoked() || key.IsDisabled() || key.IsExpired()); + [](const GpgAbstractKey* key) -> bool { + return !(key->IsRevoked() || key->IsDisabled() || key->IsExpired()); }); - m_key_list_->AddListGroupTab(tr("Favourite"), "favourite", - GpgKeyTableDisplayMode::kPUBLIC_KEY | - GpgKeyTableDisplayMode::kPRIVATE_KEY | - GpgKeyTableDisplayMode::kFAVORITES, - [](const GpgKey&) -> bool { return true; }); + m_key_list_->AddListGroupTab( + tr("Favourite"), "favourite", + GpgKeyTableDisplayMode::kPUBLIC_KEY | + GpgKeyTableDisplayMode::kPRIVATE_KEY | + GpgKeyTableDisplayMode::kFAVORITES, + [](const GpgAbstractKey*) -> bool { return true; }); m_key_list_->AddListGroupTab( tr("Only Public Key"), "only_public_key", - GpgKeyTableDisplayMode::kPUBLIC_KEY, [](const GpgKey& key) -> bool { - return !key.IsPrivateKey() && - !(key.IsRevoked() || key.IsDisabled() || key.IsExpired()); + GpgKeyTableDisplayMode::kPUBLIC_KEY, + [](const GpgAbstractKey* key) -> bool { + return !key->IsPrivateKey() && + !(key->IsRevoked() || key->IsDisabled() || key->IsExpired()); }); m_key_list_->AddListGroupTab( tr("Has Private Key"), "has_private_key", - GpgKeyTableDisplayMode::kPRIVATE_KEY, [](const GpgKey& key) -> bool { - return key.IsPrivateKey() && - !(key.IsRevoked() || key.IsDisabled() || key.IsExpired()); + GpgKeyTableDisplayMode::kPRIVATE_KEY, + [](const GpgAbstractKey* key) -> bool { + return key->IsPrivateKey() && + !(key->IsRevoked() || key->IsDisabled() || key->IsExpired()); }); m_key_list_->SlotRefresh(); @@ -606,6 +609,9 @@ void MainWindow::create_dock_windows() { info_board_dock_->setWidget(info_board_); info_board_dock_->widget()->layout()->setContentsMargins(0, 0, 0, 0); view_menu_->addAction(info_board_dock_->toggleViewAction()); + + connect(m_key_list_, &KeyList::SignalKeyChecked, this, + &MainWindow::slot_update_operations_menu_by_checked_keys); } } // namespace GpgFrontend::UI diff --git a/src/ui/model/GpgKeyTableProxyModel.cpp b/src/ui/model/GpgKeyTableProxyModel.cpp index 746f3344..90bf16d3 100644 --- a/src/ui/model/GpgKeyTableProxyModel.cpp +++ b/src/ui/model/GpgKeyTableProxyModel.cpp @@ -28,9 +28,10 @@ #include "GpgKeyTableProxyModel.h" -#include "core/function/gpg/GpgKeyGetter.h" +#include "core/function/gpg/GpgAbstractKeyGetter.h" #include "core/model/CacheObject.h" #include "core/model/GpgKey.h" +#include "core/model/GpgKeyTableModel.h" #include "core/struct/cache_object/AllFavoriteKeyPairsCO.h" #include "core/utils/GpgUtils.h" @@ -57,34 +58,31 @@ GpgKeyTableProxyModel::GpgKeyTableProxyModel( } auto GpgKeyTableProxyModel::filterAcceptsRow( - int source_row, const QModelIndex &sourceParent) const -> bool { - auto index = sourceModel()->index(source_row, 6, sourceParent); - auto key_id = sourceModel()->data(index).toString(); + int sourceRow, const QModelIndex &sourceParent) const -> bool { + auto index = sourceModel()->index(sourceRow, 0, sourceParent); - auto key = - GpgKeyGetter::GetInstance(model_->GetGpgContextChannel()).GetKey(key_id); - LOG_D() << "get key: " << key_id - << "from channel: " << model_->GetGpgContextChannel(); - assert(key.IsGood()); + auto *i = index.isValid() + ? static_cast(index.internalPointer()) + : nullptr; + assert(i != nullptr); + + auto *key = i->Key(); + assert(key->IsGood()); if (!(display_mode_ & GpgKeyTableDisplayMode::kPRIVATE_KEY) && - key.IsPrivateKey()) { + key->IsPrivateKey()) { return false; } if (!(display_mode_ & GpgKeyTableDisplayMode::kPUBLIC_KEY) && - !key.IsPrivateKey()) { + !key->IsPrivateKey()) { return false; } if (!custom_filter_(key)) return false; - if (display_mode_ & GpgKeyTableDisplayMode::kFAVORITES) { - LOG_D() << "kFAVORITES Mode" << "key id" << key_id << "favorite_key_ids_" - << favorite_key_ids_; - } if (display_mode_ & GpgKeyTableDisplayMode::kFAVORITES && - !favorite_key_ids_.contains(key_id)) { + !favorite_key_ids_.contains(key->ID())) { return false; } @@ -92,11 +90,14 @@ auto GpgKeyTableProxyModel::filterAcceptsRow( QStringList infos; for (int column = 0; column < sourceModel()->columnCount(); ++column) { - auto index = sourceModel()->index(source_row, column, sourceParent); + auto index = sourceModel()->index(sourceRow, column, sourceParent); infos << sourceModel()->data(index).toString(); - for (const auto &uid : key.UIDs()) { - infos << uid.GetUID(); + if (key->KeyType() == GpgAbstractKeyType::kGPG_KEY) { + auto *k = dynamic_cast(key); + for (const auto &uid : k->UIDs()) { + infos << uid.GetUID(); + } } } @@ -197,4 +198,8 @@ void GpgKeyTableProxyModel::slot_update_favorites_cache() { } } +void GpgKeyTableProxyModel::SetFilter(const KeyFilter &filter) { + this->custom_filter_ = filter; + invalidateFilter(); +} } // namespace GpgFrontend::UI \ No newline at end of file diff --git a/src/ui/model/GpgKeyTableProxyModel.h b/src/ui/model/GpgKeyTableProxyModel.h index bad1aa97..5b9c0336 100644 --- a/src/ui/model/GpgKeyTableProxyModel.h +++ b/src/ui/model/GpgKeyTableProxyModel.h @@ -38,7 +38,7 @@ namespace GpgFrontend::UI { class GpgKeyTableProxyModel : public QSortFilterProxyModel { Q_OBJECT public: - using KeyFilter = std::function; + using KeyFilter = std::function; explicit GpgKeyTableProxyModel(QSharedPointer model, GpgKeyTableDisplayMode display_mode, @@ -47,6 +47,8 @@ class GpgKeyTableProxyModel : public QSortFilterProxyModel { void SetSearchKeywords(const QString &keywords); + void SetFilter(const KeyFilter &filter); + void ResetGpgKeyTableModel(QSharedPointer model); protected: diff --git a/src/ui/model/GpgKeyTreeProxyModel.cpp b/src/ui/model/GpgKeyTreeProxyModel.cpp index 2f46f548..bff18dd6 100644 --- a/src/ui/model/GpgKeyTreeProxyModel.cpp +++ b/src/ui/model/GpgKeyTreeProxyModel.cpp @@ -28,7 +28,6 @@ #include "GpgKeyTreeProxyModel.h" -#include "core/function/gpg/GpgKeyGetter.h" #include "core/model/CacheObject.h" #include "core/model/GpgKey.h" #include "core/model/GpgKeyTreeModel.h" @@ -83,7 +82,7 @@ auto GpgKeyTreeProxyModel::filterAcceptsRow( auto index = sourceModel()->index(source_row, column, sourceParent); infos << sourceModel()->data(index).toString(); - if (!key->IsSubKey()) { + if (key->KeyType() != GpgAbstractKeyType::kGPG_SUBKEY) { for (const auto &uid : dynamic_cast(key)->UIDs()) { infos << uid.GetUID(); } diff --git a/src/ui/struct/GpgOperaResultContext.h b/src/ui/struct/GpgOperaResultContext.h index 58da0dc8..10a1bad9 100644 --- a/src/ui/struct/GpgOperaResultContext.h +++ b/src/ui/struct/GpgOperaResultContext.h @@ -48,8 +48,8 @@ struct GpgOperaContext; struct GpgOperaContextBasement { QContainer operas; QContainer opera_results; - GpgKeyList keys; - GpgKeyList singer_keys; + GpgAbstractKeyPtrList keys; + GpgAbstractKeyPtrList singer_keys; QStringList unknown_fprs; bool ascii; diff --git a/src/ui/widgets/KeyList.cpp b/src/ui/widgets/KeyList.cpp index fb26295f..429a5bd1 100644 --- a/src/ui/widgets/KeyList.cpp +++ b/src/ui/widgets/KeyList.cpp @@ -31,34 +31,50 @@ #include #include "core/function/GlobalSettingStation.h" +#include "core/function/gpg/GpgAbstractKeyGetter.h" #include "core/function/gpg/GpgKeyGetter.h" #include "core/utils/GpgUtils.h" #include "ui/UISignalStation.h" #include "ui/UserInterfaceUtils.h" +#include "ui/dialog/KeyGroupCreationDialog.h" #include "ui/dialog/import_export/KeyImportDetailDialog.h" + +// #include "ui_KeyList.h" namespace GpgFrontend::UI { +KeyList::KeyList(QWidget* parent) + : QWidget(parent), + ui_(GpgFrontend::SecureCreateSharedObject()), + model_(GpgAbstractKeyGetter::GetInstance(kGpgFrontendDefaultChannel) + .GetGpgKeyTableModel()), + global_column_filter_(static_cast( + GetSettings() + .value("keys/global_columns_filter", + static_cast(GpgKeyTableColumn::kALL)) + .toUInt())) { + ui_->setupUi(this); +} + KeyList::KeyList(int channel, KeyMenuAbility menu_ability, GpgKeyTableColumn fixed_columns_filter, QWidget* parent) : QWidget(parent), ui_(GpgFrontend::SecureCreateSharedObject()), current_gpg_context_channel_(channel), menu_ability_(menu_ability), - model_(GpgKeyGetter::GetInstance(channel).GetGpgKeyTableModel()), + model_(GpgAbstractKeyGetter::GetInstance(channel).GetGpgKeyTableModel()), fixed_columns_filter_(fixed_columns_filter), global_column_filter_(static_cast( GetSettings() .value("keys/global_columns_filter", static_cast(GpgKeyTableColumn::kALL)) .toUInt())) { + ui_->setupUi(this); init(); } void KeyList::init() { - ui_->setupUi(this); - ui_->menuWidget->setHidden(menu_ability_ == KeyMenuAbility::kNONE); ui_->refreshKeyListButton->setHidden(~menu_ability_ & KeyMenuAbility::kREFRESH); @@ -70,6 +86,7 @@ void KeyList::init() { ui_->searchBarEdit->setHidden(~menu_ability_ & KeyMenuAbility::kSEARCH_BAR); ui_->switchContextButton->setHidden(~menu_ability_ & KeyMenuAbility::kKEY_DATABASE); + ui_->keyGroupButton->setHidden(~menu_ability_ & KeyMenuAbility::kKEY_GROUP); auto* gpg_context_menu = new QMenu(this); auto* gpg_context_groups = new QActionGroup(this); @@ -243,6 +260,16 @@ void KeyList::init() { GetSettings().setValue("keys/global_columns_filter", static_cast(global_column_filter_)); }); + connect(ui_->keyGroupButton, &QPushButton::clicked, this, + &KeyList::slot_new_key_group); + connect(this, &KeyList::SignalKeyChecked, this, [=]() { + auto keys = GetCheckedKeys(); + + ui_->keyGroupButton->setDisabled(keys.empty()); + for (const auto& key : keys) { + if (!key->IsHasEncrCap()) ui_->keyGroupButton->setDisabled(true); + } + }); setAcceptDrops(true); @@ -261,10 +288,10 @@ void KeyList::init() { ui_->searchBarEdit->setPlaceholderText(tr("Search for keys...")); } -void KeyList::AddListGroupTab(const QString& name, const QString& id, - GpgKeyTableDisplayMode display_mode, - GpgKeyTableProxyModel::KeyFilter search_filter, - GpgKeyTableColumn custom_columns_filter) { +auto KeyList::AddListGroupTab( + const QString& name, const QString& id, GpgKeyTableDisplayMode display_mode, + GpgKeyTableProxyModel::KeyFilter search_filter, + GpgKeyTableColumn custom_columns_filter) -> KeyTable* { auto* key_table = new KeyTable(this, model_, display_mode, custom_columns_filter, std::move(search_filter)); @@ -274,8 +301,13 @@ void KeyList::AddListGroupTab(const QString& name, const QString& id, connect(this, &KeyList::SignalColumnTypeChange, key_table, &KeyTable::SignalColumnTypeChange); + connect(key_table, &KeyTable::SignalKeyChecked, this, [=]() { + if (sender() != ui_->keyGroupTab->currentWidget()) return; + emit SignalKeyChecked(); + }); UpdateKeyTableColumnType(global_column_filter_); + return key_table; } void KeyList::SlotRefresh() { @@ -284,7 +316,7 @@ void KeyList::SlotRefresh() { LOG_D() << "request new key table module, current gpg context channel: " << current_gpg_context_channel_; - model_ = GpgKeyGetter::GetInstance(current_gpg_context_channel_) + model_ = GpgAbstractKeyGetter::GetInstance(current_gpg_context_channel_) .GetGpgKeyTableModel(); for (int i = 0; i < ui_->keyGroupTab->count(); i++) { @@ -300,112 +332,54 @@ void KeyList::SlotRefreshUI() { emit SignalRefreshStatusBar(tr("Key List Refreshed."), 1000); ui_->refreshKeyListButton->setDisabled(false); ui_->syncButton->setDisabled(false); + emit SignalKeyChecked(); } -auto KeyList::GetChecked(const KeyTable& key_table) -> KeyIdArgsList { - auto ret = KeyIdArgsList{}; - for (int i = 0; i < key_table.GetRowCount(); i++) { - if (key_table.IsRowChecked(i)) { - ret.push_back(key_table.GetKeyIdByRow(i)); - } - } - return ret; -} - -auto KeyList::GetChecked() -> KeyIdArgsList { +auto KeyList::GetCheckedKeys() -> GpgAbstractKeyPtrList { auto* key_table = qobject_cast(ui_->keyGroupTab->currentWidget()); - auto ret = KeyIdArgsList{}; - for (int i = 0; i < key_table->GetRowCount(); i++) { - if (key_table->IsRowChecked(i)) { - ret.push_back(key_table->GetKeyIdByRow(i)); - } - } - return ret; -} -auto KeyList::GetCheckedKeys() -> QStringList { - auto* key_table = qobject_cast(ui_->keyGroupTab->currentWidget()); - QStringList key_id_list; - for (int i = 0; i < key_table->GetRowCount(); i++) { - if (key_table->IsRowChecked(i)) { - key_id_list.append(key_table->GetKeyIdByRow(i)); - } - } - return key_id_list; -} + assert(key_table != nullptr); + if (key_table == nullptr) return {}; -auto KeyList::GetAllPrivateKeys() -> KeyIdArgsList { - auto* key_table = qobject_cast(ui_->keyGroupTab->currentWidget()); - auto ret = KeyIdArgsList{}; - for (int i = 0; i < key_table->GetRowCount(); i++) { - if (key_table->IsPrivateKeyByRow(i)) { - ret.push_back(key_table->GetKeyIdByRow(i)); - } - } - return ret; + return key_table->GetCheckedKeys(); } -auto KeyList::GetCheckedPrivateKey() -> KeyIdArgsList { - auto ret = KeyIdArgsList{}; - if (ui_->keyGroupTab->size().isEmpty()) return ret; - - auto* key_table = qobject_cast(ui_->keyGroupTab->currentWidget()); +auto KeyList::GetCheckedPrivateKey() -> GpgAbstractKeyPtrList { + auto ret = GpgAbstractKeyPtrList{}; - for (int i = 0; i < key_table->GetRowCount(); i++) { - if (key_table->IsRowChecked(i) && key_table->IsPrivateKeyByRow(i)) { - ret.push_back(key_table->GetKeyIdByRow(i)); - } + auto keys = GetCheckedKeys(); + for (const auto& key : keys) { + if (key->IsPrivateKey()) ret.push_back(key); } + return ret; } -auto KeyList::GetCheckedPublicKey() -> KeyIdArgsList { - auto ret = KeyIdArgsList{}; - if (ui_->keyGroupTab->size().isEmpty()) return ret; +auto KeyList::GetCheckedPublicKey() -> GpgAbstractKeyPtrList { + auto ret = GpgAbstractKeyPtrList{}; - auto* key_table = qobject_cast(ui_->keyGroupTab->currentWidget()); - - for (int i = 0; i < key_table->GetRowCount(); i++) { - if (key_table->IsRowChecked(i) && key_table->IsPublicKeyByRow(i)) { - ret.push_back(key_table->GetKeyIdByRow(i)); - } + auto keys = GetCheckedKeys(); + for (const auto& key : keys) { + if (!key->IsPrivateKey()) ret.push_back(key); } + return ret; } -void KeyList::SetChecked(const KeyIdArgsList& keyIds, +void KeyList::SetChecked(const KeyIdArgsList& key_ids, const KeyTable& key_table) { - if (!keyIds.empty()) { + if (!key_ids.empty()) { for (int i = 0; i < key_table.GetRowCount(); i++) { - if (std::find(keyIds.begin(), keyIds.end(), key_table.GetKeyIdByRow(i)) != - keyIds.end()) { + if (std::find( + key_ids.begin(), key_ids.end(), + key_table.GetKeyByIndex(key_table.model()->index(i, 0))->ID()) != + key_ids.end()) { key_table.SetRowChecked(i); } } } } -auto KeyList::GetSelected() -> KeyIdArgsList { - auto ret = KeyIdArgsList{}; - if (ui_->keyGroupTab->size().isEmpty()) return ret; - - auto* key_table = qobject_cast(ui_->keyGroupTab->currentWidget()); - if (key_table == nullptr) { - FLOG_W("fail to get current key table, nullptr"); - return ret; - } - - QItemSelectionModel* select = key_table->selectionModel(); - for (auto index : select->selectedRows()) { - ret.push_back(key_table->GetKeyIdByRow(index.row())); - } - - if (ret.empty()) { - FLOG_W("nothing is selected at key list"); - } - return ret; -} - [[maybe_unused]] auto KeyList::ContainsPrivateKeys() -> bool { if (ui_->keyGroupTab->size().isEmpty()) return false; auto* key_table = @@ -532,24 +506,29 @@ void KeyList::import_keys(const QByteArray& in_buffer) { (new KeyImportDetailDialog(current_gpg_context_channel_, result, this)); } -auto KeyList::GetSelectedKey() -> QString { - if (ui_->keyGroupTab->size().isEmpty()) return {}; - - auto* key_table = qobject_cast(ui_->keyGroupTab->currentWidget()); - - QItemSelectionModel* select = key_table->selectionModel(); +auto KeyList::GetSelectedKey() -> GpgAbstractKeyPtr { + return GetSelectedKeys().front(); +} - auto selected_rows = select->selectedRows(); - if (selected_rows.empty()) return {}; +auto KeyList::GetSelectedGpgKey() -> GpgKeyPtr { + return GetSelectedGpgKeys().front(); +} - return key_table->GetKeyIdByRow(selected_rows.first().row()); +auto KeyList::GetSelectedGpgKeys() -> GpgKeyPtrList { + auto keys = GetSelectedKeys(); + auto g_keys = GpgKeyPtrList{}; + for (const auto& key : keys) { + if (key->KeyType() != GpgAbstractKeyType::kGPG_KEY) continue; + g_keys.push_back(qSharedPointerDynamicCast(key)); + } + return g_keys; } void KeyList::slot_sync_with_key_server() { - auto checked_public_keys = GetCheckedPublicKey(); + auto target_keys = GetCheckedPublicKey(); KeyIdArgsList key_ids; - if (checked_public_keys.empty()) { + if (target_keys.empty()) { QMessageBox::StandardButton const reply = QMessageBox::question( this, QCoreApplication::tr("Sync All Public Key"), QCoreApplication::tr("You have not checked any public keys that you " @@ -559,13 +538,12 @@ void KeyList::slot_sync_with_key_server() { if (reply == QMessageBox::No) return; - auto all_key_ids = model_->GetAllKeyIds(); - for (auto& key_id : all_key_ids) { - key_ids.push_back(key_id); - } + target_keys = model_->GetAllKeys(); + } - } else { - key_ids = checked_public_keys; + for (auto& key : target_keys) { + if (key->KeyType() != GpgAbstractKeyType::kGPG_KEY) continue; + key_ids.push_back(key->ID()); } if (key_ids.empty()) return; @@ -633,18 +611,59 @@ auto KeyList::GetCurrentGpgContextChannel() const -> int { return current_gpg_context_channel_; } -auto KeyList::GetSelectedGpgKey() -> std::tuple { - auto key_ids = GetSelected(); - if (key_ids.empty()) return {false, GpgKey()}; +auto KeyList::GetSelectedKeys() -> GpgAbstractKeyPtrList { + auto* key_table = qobject_cast(ui_->keyGroupTab->currentWidget()); + + assert(key_table != nullptr); + if (key_table == nullptr) return {}; + + return key_table->GetSelectedKeys(); +} + +void KeyList::slot_new_key_group() { + auto keys = GetCheckedKeys(); + + QStringList proper_key_ids; + for (const auto& key : keys) { + if (!key->IsHasEncrCap()) continue; + proper_key_ids.append(key->ID()); + } + + if (proper_key_ids.isEmpty()) return; + + auto* dialog = + new KeyGroupCreationDialog(current_gpg_context_channel_, proper_key_ids); + dialog->exec(); +} + +void KeyList::UpdateKeyTableFilter( + int index, const GpgKeyTableProxyModel::KeyFilter& filter) { + if (ui_->keyGroupTab->size().isEmpty() || + ui_->keyGroupTab->widget(index) == nullptr) { + return; + } - auto key = GpgKeyGetter::GetInstance(GetCurrentGpgContextChannel()) - .GetKey(key_ids.front()); + auto* key_table = qobject_cast(ui_->keyGroupTab->widget(index)); + key_table->SetFilter(filter); +} - if (!key.IsGood()) { - QMessageBox::critical(this, tr("Error"), tr("Key Not Found.")); - return {false, GpgKey()}; +void KeyList::RefreshKeyTable(int index) { + if (ui_->keyGroupTab->size().isEmpty() || + ui_->keyGroupTab->widget(index) == nullptr) { + return; } - return {true, key}; + auto* key_table = qobject_cast(ui_->keyGroupTab->widget(index)); + key_table->RefreshProxyModel(); +} + +void KeyList::Init(int channel, KeyMenuAbility menu_ability, + GpgKeyTableColumn fixed_column_filter) { + current_gpg_context_channel_ = channel; + menu_ability_ = menu_ability; + fixed_columns_filter_ = fixed_column_filter; + model_ = GpgAbstractKeyGetter::GetInstance(channel).GetGpgKeyTableModel(); + + init(); } } // namespace GpgFrontend::UI diff --git a/src/ui/widgets/KeyList.h b/src/ui/widgets/KeyList.h index 868c5b07..0b0b9be6 100644 --- a/src/ui/widgets/KeyList.h +++ b/src/ui/widgets/KeyList.h @@ -47,6 +47,7 @@ enum class KeyMenuAbility : unsigned int { kCOLUMN_FILTER = 1 << 4, kSEARCH_BAR = 1 << 5, kKEY_DATABASE = 1 << 6, + kKEY_GROUP = 1 << 7, kALL = ~0U }; @@ -81,6 +82,12 @@ class KeyList : public QWidget { Q_OBJECT public: + /** + * @brief Construct a new Key List object + * + */ + explicit KeyList(QWidget* parent = nullptr); + /** * @brief Construct a new Key List object * @@ -92,6 +99,16 @@ class KeyList : public QWidget { GpgKeyTableColumn fixed_column_filter = GpgKeyTableColumn::kALL, QWidget* parent = nullptr); + /** + * @brief + * + * @param channel + * @param menu_ability + * @param fixed_column_filter + */ + void Init(int channel, KeyMenuAbility menu_ability, + GpgKeyTableColumn fixed_column_filter = GpgKeyTableColumn::kALL); + /** * @brief * @@ -100,13 +117,14 @@ class KeyList : public QWidget { * @param infoType * @param filter */ - void AddListGroupTab( + auto AddListGroupTab( const QString& name, const QString& id, GpgKeyTableDisplayMode display_mode = GpgKeyTableDisplayMode::kPRIVATE_KEY, GpgKeyTableProxyModel::KeyFilter search_filter = - [](const GpgKey&) -> bool { return true; }, - GpgKeyTableColumn custom_columns_filter = GpgKeyTableColumn::kALL); + [](const GpgAbstractKey*) -> bool { return true; }, + GpgKeyTableColumn custom_columns_filter = GpgKeyTableColumn::kALL) + -> KeyTable*; /** * @brief Set the Column Width object @@ -129,19 +147,12 @@ class KeyList : public QWidget { */ void AddSeparator(); - /** - * @brief Get the Checked object - * - * @return KeyIdArgsListPtr - */ - auto GetChecked() -> KeyIdArgsList; - /** * @brief Get the Checked Keys object * * @return QStringList */ - auto GetCheckedKeys() -> QStringList; + auto GetCheckedKeys() -> GpgAbstractKeyPtrList; /** * @brief Get the Checked object @@ -149,28 +160,21 @@ class KeyList : public QWidget { * @param key_table * @return KeyIdArgsListPtr */ - static auto GetChecked(const KeyTable& key_table) -> KeyIdArgsList; + static auto GetChecked(const KeyTable& key_table) -> GpgAbstractKeyPtrList; /** * @brief Get the Private Checked object * * @return KeyIdArgsListPtr */ - auto GetCheckedPrivateKey() -> KeyIdArgsList; + auto GetCheckedPrivateKey() -> GpgAbstractKeyPtrList; /** * @brief * * @return KeyIdArgsListPtr */ - auto GetCheckedPublicKey() -> KeyIdArgsList; - - /** - * @brief Get the All Private Keys object - * - * @return KeyIdArgsListPtr - */ - auto GetAllPrivateKeys() -> KeyIdArgsList; + auto GetCheckedPublicKey() -> GpgAbstractKeyPtrList; /** * @brief Set the Checked object @@ -182,25 +186,32 @@ class KeyList : public QWidget { const KeyTable& key_table); /** - * @brief Get the Selected object + * @brief Get the Selected Key object * - * @return KeyIdArgsListPtr + * @return QString */ - auto GetSelected() -> KeyIdArgsList; + auto GetSelectedKey() -> GpgAbstractKeyPtr; + + /** + * @brief Get the Selected Keys object + * + * @return GpgAbstractKeyPtrList + */ + auto GetSelectedKeys() -> GpgAbstractKeyPtrList; /** * @brief Get the Selected Key object * * @return QString */ - auto GetSelectedKey() -> QString; + auto GetSelectedGpgKey() -> GpgKeyPtr; /** - * @brief Get the Selected Gpg Key object + * @brief Get the Selected Keys object * - * @return GpgKey + * @return GpgAbstractKeyPtrList */ - auto GetSelectedGpgKey() -> std::tuple; + auto GetSelectedGpgKeys() -> GpgKeyPtrList; /** * @brief @@ -223,6 +234,33 @@ class KeyList : public QWidget { */ [[nodiscard]] auto GetCurrentGpgContextChannel() const -> int; + /** + * @brief + * + */ + void UpdateKeyTableFilter(int index, const GpgKeyTableProxyModel::KeyFilter&); + + /** + * @brief + * + * @param index + */ + void RefreshKeyTable(int index); + + public slots: + + /** + * @brief + * + */ + void SlotRefresh(); + + /** + * @brief + * + */ + void SlotRefreshUI(); + signals: /** * @brief @@ -244,52 +282,49 @@ class KeyList : public QWidget { */ void SignalColumnTypeChange(GpgKeyTableColumn); - public slots: - /** * @brief * */ - void SlotRefresh(); + void SignalKeyChecked(); + protected: /** * @brief * + * @param event */ - void SlotRefreshUI(); + void contextMenuEvent(QContextMenuEvent* event) override; - private: /** * @brief * + * @param event */ - void init(); + void dragEnterEvent(QDragEnterEvent* event) override; /** * @brief * - * @param inBuffer + * @param event */ - void import_keys(const QByteArray& in_buffer); + void dropEvent(QDropEvent* event) override; - /** - * @brief - * - */ - void uncheck_all(); + private slots: /** * @brief * */ - void check_all(); + void slot_sync_with_key_server(); /** * @brief * */ - void filter_by_keyword(); + void slot_new_key_group(); + private: std::shared_ptr ui_; ///< QMenu* popup_menu_{}; ///< std::function m_action_ = nullptr; ///< @@ -306,35 +341,36 @@ class KeyList : public QWidget { QAction* subkeys_number_column_action_; QAction* comment_column_action_; - private slots: + /** + * @brief + * + */ + void init(); /** * @brief * + * @param inBuffer */ - void slot_sync_with_key_server(); + void import_keys(const QByteArray& in_buffer); - protected: /** * @brief * - * @param event */ - void contextMenuEvent(QContextMenuEvent* event) override; + void uncheck_all(); /** * @brief * - * @param event */ - void dragEnterEvent(QDragEnterEvent* event) override; + void check_all(); /** * @brief * - * @param event */ - void dropEvent(QDropEvent* event) override; + void filter_by_keyword(); }; } // namespace GpgFrontend::UI diff --git a/src/ui/widgets/KeyTable.cpp b/src/ui/widgets/KeyTable.cpp index 10ebe6eb..d1135279 100644 --- a/src/ui/widgets/KeyTable.cpp +++ b/src/ui/widgets/KeyTable.cpp @@ -28,16 +28,16 @@ #include "ui/widgets/KeyTable.h" -#include "core/function/gpg/GpgKeyGetter.h" #include "ui/UserInterfaceUtils.h" -#include "ui/dialog/keypair_details/KeyDetailsDialog.h" namespace GpgFrontend::UI { -auto KeyTable::GetChecked() const -> KeyIdArgsList { - auto ret = KeyIdArgsList{}; +auto KeyTable::GetCheckedKeys() const -> GpgAbstractKeyPtrList { + auto ret = GpgAbstractKeyPtrList{}; for (decltype(GetRowCount()) i = 0; i < GetRowCount(); i++) { - if (IsRowChecked(i)) ret.push_back(GetKeyIdByRow(i)); + if (IsRowChecked(i)) { + ret.push_back(GetKeyByIndex(model()->index(i, 0))); + } } return ret; } @@ -76,15 +76,20 @@ KeyTable::KeyTable(QWidget* parent, QSharedPointer model, }); connect(this, &QTableView::doubleClicked, this, [this](const QModelIndex& index) { - if (!index.isValid() || index.column() == 0) return; - - auto key = GpgKeyGetter::GetInstance(model_->GetGpgContextChannel()) - .GetKey(GetKeyIdByRow(index.row())); - if (!key.IsGood()) { - QMessageBox::critical(this, tr("Error"), tr("Key Not Found.")); - return; - } - new KeyDetailsDialog(model_->GetGpgContextChannel(), key, this); + if (!index.isValid()) return; + + auto key = GetKeyByIndex(index); + if (key == nullptr) return; + + CommonUtils::OpenDetailsDialogByKey( + this, model_->GetGpgContextChannel(), key); + }); + + connect(&proxy_model_, &GpgKeyTableProxyModel::dataChanged, this, + [=](const QModelIndex&, const QModelIndex&, + const QContainer& roles) { + if (!roles.contains(Qt::CheckStateRole)) return; + emit SignalKeyChecked(); }); } @@ -104,22 +109,22 @@ auto KeyTable::IsRowChecked(int row) const -> bool { auto KeyTable::GetRowCount() const -> int { return model()->rowCount(); } -auto KeyTable::GetKeyIdByRow(int row) const -> QString { - if (row < 0 || row >= model()->rowCount()) return {}; - auto origin_row = model()->index(row, 0).data().toInt(); - return model_->GetKeyIDByRow(origin_row); -} +auto KeyTable::GetKeyByIndex(QModelIndex index) const -> GpgAbstractKeyPtr { + auto idx = proxy_model_.mapToSource(index); + auto* i = idx.isValid() ? static_cast(idx.internalPointer()) + : nullptr; + assert(i != nullptr); -auto KeyTable::IsPrivateKeyByRow(int row) const -> bool { - if (row < 0 || row >= model()->rowCount()) return false; - auto origin_row = model()->index(row, 0).data().toInt(); - return model_->IsPrivateKeyByRow(origin_row); + return i->SharedKey(); } -auto KeyTable::IsPublicKeyByRow(int row) const -> bool { - if (row < 0 || row >= model()->rowCount()) return false; - auto origin_row = model()->index(row, 0).data().toInt(); - return !model_->IsPrivateKeyByRow(origin_row); +auto KeyTable::GetSelectedKeys() const -> GpgAbstractKeyPtrList { + GpgAbstractKeyPtrList ret; + QItemSelectionModel* select = selectionModel(); + for (auto index : select->selectedRows()) { + ret.push_back(GetKeyByIndex(index)); + } + return ret; } void KeyTable::SetRowChecked(int row) const { @@ -148,4 +153,9 @@ void KeyTable::UncheckAll() { return selected_indexes.first().row(); } +void KeyTable::SetFilter(const GpgKeyTableProxyModel::KeyFilter& filter) { + proxy_model_.SetFilter(filter); +} + +void KeyTable::RefreshProxyModel() { proxy_model_.invalidate(); } } // namespace GpgFrontend::UI \ No newline at end of file diff --git a/src/ui/widgets/KeyTable.h b/src/ui/widgets/KeyTable.h index fe73bc98..9f6d1ba5 100644 --- a/src/ui/widgets/KeyTable.h +++ b/src/ui/widgets/KeyTable.h @@ -54,9 +54,8 @@ struct KeyTable : public QTableView { KeyTable( QWidget* parent, QSharedPointer model, GpgKeyTableDisplayMode _select_type, GpgKeyTableColumn _info_type, - GpgKeyTableProxyModel::KeyFilter _filter = [](const GpgKey&) -> bool { - return true; - }); + GpgKeyTableProxyModel::KeyFilter _filter = + [](const GpgAbstractKey*) -> bool { return true; }); /** * @brief @@ -70,7 +69,7 @@ struct KeyTable : public QTableView { * * @return KeyIdArgsListPtr& */ - [[nodiscard]] auto GetChecked() const -> KeyIdArgsList; + [[nodiscard]] auto GetCheckedKeys() const -> GpgAbstractKeyPtrList; /** * @brief @@ -121,42 +120,45 @@ struct KeyTable : public QTableView { [[nodiscard]] auto GetRowCount() const -> int; /** - * @brief Get the Key Id By Row object + * @brief * - * @param row - * @return QString + * @param index + * @return GpgAbstractKeyPtr + */ + [[nodiscard]] auto GetKeyByIndex(QModelIndex index) const + -> GpgAbstractKeyPtr; + + /** + * @brief Get the Selected Keys object + * + * @param index + * @return GpgAbstractKeyPtrList */ - [[nodiscard]] auto GetKeyIdByRow(int row) const -> QString; + [[nodiscard]] auto GetSelectedKeys() const -> GpgAbstractKeyPtrList; /** * @brief * - * @param row - * @return true - * @return false */ - [[nodiscard]] auto IsPublicKeyByRow(int row) const -> bool; + void CheckAll(); /** * @brief * - * @param row - * @return true - * @return false */ - [[nodiscard]] auto IsPrivateKeyByRow(int row) const -> bool; + void UncheckAll(); /** * @brief * */ - void CheckAll(); + void SetFilter(const GpgKeyTableProxyModel::KeyFilter&); /** * @brief * */ - void UncheckAll(); + void RefreshProxyModel(); signals: @@ -172,6 +174,12 @@ struct KeyTable : public QTableView { */ void SignalGpgContextChannelChange(int); + /** + * @brief + * + */ + void SignalKeyChecked(); + private: QSharedPointer model_; GpgKeyTableProxyModel proxy_model_; diff --git a/src/ui/widgets/KeyTreeView.cpp b/src/ui/widgets/KeyTreeView.cpp index c0a00c4e..46cfa2db 100644 --- a/src/ui/widgets/KeyTreeView.cpp +++ b/src/ui/widgets/KeyTreeView.cpp @@ -31,9 +31,8 @@ #include #include "core/function/gpg/GpgKeyGetter.h" -#include "core/utils/GpgUtils.h" #include "ui/UISignalStation.h" -#include "ui/dialog/keypair_details/KeyDetailsDialog.h" +#include "ui/UserInterfaceUtils.h" #include "ui/model/GpgKeyTreeProxyModel.h" namespace GpgFrontend::UI { @@ -109,18 +108,13 @@ void KeyTreeView::init() { connect(this, &QTableView::doubleClicked, this, [this](const QModelIndex& index) { - if (!index.isValid() || index.column() == 0) return; + if (!index.isValid()) return; - QModelIndex source_index = proxy_model_.mapToSource(index); - auto key = - GetGpgKeyByGpgAbstractKey(model_->GetKeyByIndex(source_index)); + auto key = GetKeyByIndex(index); + if (key == nullptr) return; - if (!key.IsGood()) { - QMessageBox::critical(this, tr("Error"), tr("Key Not Found.")); - return; - } - - new KeyDetailsDialog(model_->GetGpgContextChannel(), key, this); + CommonUtils::OpenDetailsDialogByKey( + this, model_->GetGpgContextChannel(), key); }); connect(UISignalStation::GetInstance(), @@ -150,4 +144,12 @@ void KeyTreeView::SetChannel(int channel) { proxy_model_.invalidate(); } +auto KeyTreeView::GetKeyByIndex(QModelIndex index) -> GpgAbstractKeyPtr { + auto* i = index.isValid() + ? static_cast(index.internalPointer()) + : nullptr; + assert(i != nullptr); + + return i->SharedKey(); +} } // namespace GpgFrontend::UI diff --git a/src/ui/widgets/KeyTreeView.h b/src/ui/widgets/KeyTreeView.h index 0e12ad0b..af903273 100644 --- a/src/ui/widgets/KeyTreeView.h +++ b/src/ui/widgets/KeyTreeView.h @@ -63,6 +63,14 @@ class KeyTreeView : public QTreeView { GpgKeyTreeProxyModel::KeyFilter filter, QWidget* parent = nullptr); + /** + * @brief Get the Key By Index object + * + * @param index + * @return GpgAbstractKeyPtr + */ + static auto GetKeyByIndex(QModelIndex index) -> GpgAbstractKeyPtr; + /** * @brief Get the All Checked Key Ids object * diff --git a/src/ui/widgets/VerifyKeyDetailBox.cpp b/src/ui/widgets/VerifyKeyDetailBox.cpp index eca7f03c..0cad1b6e 100644 --- a/src/ui/widgets/VerifyKeyDetailBox.cpp +++ b/src/ui/widgets/VerifyKeyDetailBox.cpp @@ -28,7 +28,6 @@ #include "ui/widgets/VerifyKeyDetailBox.h" -#include "core/GpgModel.h" #include "core/function/GlobalSettingStation.h" #include "core/function/gpg/GpgKeyGetter.h" #include "core/utils/CommonUtils.h" @@ -41,7 +40,8 @@ VerifyKeyDetailBox::VerifyKeyDetailBox(int channel, QWidget* parent) : QGroupBox(parent), current_gpg_context_channel_(channel), - fpr_(signature.GetFingerprint()) { + key_(GpgKeyGetter::GetInstance(channel).GetKeyPtr( + signature.GetFingerprint())) { auto* vbox = new QVBoxLayout(); switch (gpg_err_code(signature.GetStatus())) { @@ -58,7 +58,7 @@ VerifyKeyDetailBox::VerifyKeyDetailBox(int channel, connect(import_button, &QPushButton::clicked, this, &VerifyKeyDetailBox::slot_import_form_key_server); - this->setTitle(tr("Key not present with id 0x") + fpr_); + this->setTitle(tr("Key not present with id 0x") + key_->ID()); auto* grid = new QGridLayout(); @@ -166,27 +166,26 @@ VerifyKeyDetailBox::VerifyKeyDetailBox(int channel, } void VerifyKeyDetailBox::slot_import_form_key_server() { - CommonUtils::GetInstance()->ImportKeyFromKeyServer( - current_gpg_context_channel_, {fpr_}); + CommonUtils::GetInstance()->ImportGpgKeyFromKeyServer( + current_gpg_context_channel_, {key_}); } auto VerifyKeyDetailBox::create_key_info_grid(const GpgSignature& signature) -> QGridLayout* { auto* grid = new QGridLayout(); - auto key = - GpgKeyGetter::GetInstance(current_gpg_context_channel_).GetKey(fpr_); - assert(key.IsGood()); - if (!key.IsGood()) return nullptr; + assert(key_->IsGood()); + if (!key_->IsGood()) return nullptr; + grid->addWidget(new QLabel(tr("Signer Name") + ":"), 0, 0); grid->addWidget(new QLabel(tr("Signer Email") + ":"), 1, 0); grid->addWidget(new QLabel(tr("Key's Fingerprint") + ":"), 2, 0); grid->addWidget(new QLabel(tr("Valid") + ":"), 3, 0); grid->addWidget(new QLabel(tr("Flags") + ":"), 4, 0); - grid->addWidget(new QLabel(key.Name()), 0, 1); - grid->addWidget(new QLabel(key.Email()), 1, 1); - grid->addWidget(new QLabel(BeautifyFingerprint(fpr_)), 2, 1); + grid->addWidget(new QLabel(key_->Name()), 0, 1); + grid->addWidget(new QLabel(key_->Email()), 1, 1); + grid->addWidget(new QLabel(BeautifyFingerprint(key_->Fingerprint())), 2, 1); if ((signature.GetSummary() & GPGME_SIGSUM_VALID) != 0U) { grid->addWidget(new QLabel(tr("Fully Valid")), 3, 1); diff --git a/src/ui/widgets/VerifyKeyDetailBox.h b/src/ui/widgets/VerifyKeyDetailBox.h index 55bcb7ec..39f2aaca 100644 --- a/src/ui/widgets/VerifyKeyDetailBox.h +++ b/src/ui/widgets/VerifyKeyDetailBox.h @@ -65,7 +65,7 @@ class VerifyKeyDetailBox : public QGroupBox { QGridLayout* create_key_info_grid(const GpgSignature& signature); int current_gpg_context_channel_; - QString fpr_; ///< fingerprint of the key + GpgKeyPtr key_; ///< fingerprint of the key }; } // namespace GpgFrontend::UI diff --git a/ui/KeyGroupManageDialog.ui b/ui/KeyGroupManageDialog.ui new file mode 100644 index 00000000..ea0225e3 --- /dev/null +++ b/ui/KeyGroupManageDialog.ui @@ -0,0 +1,121 @@ + + + KeyGroupManageDialog + + + + 0 + 0 + 1005 + 647 + + + + Key Group Management + + + + + + + + Key(s) in Key Group: + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + + + + + + + + Qt::Orientation::Vertical + + + + 20 + 40 + + + + + + + + << + + + + + + + >> + + + + + + + Qt::Orientation::Vertical + + + + 20 + 40 + + + + + + + + + + + + Key(s) in Key Dayabase: + + + + + + + + 0 + 0 + + + + + + + + + + + GpgFrontend::UI::KeyList + QWidget +
ui/widgets/KeyList.h
+ 1 +
+
+ + +
diff --git a/ui/KeyList.ui b/ui/KeyList.ui index d29bdcb8..ba190954 100644 --- a/ui/KeyList.ui +++ b/ui/KeyList.ui @@ -142,6 +142,17 @@ + + + + ... + + + + :/icons/key-group.png:/icons/key-group.png + + + -- cgit v1.2.3