aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsaturneric <[email protected]>2023-12-27 03:20:11 +0000
committersaturneric <[email protected]>2023-12-27 03:20:11 +0000
commit566d5e41a34e08b06a5c84fd4ad9f944b6b31feb (patch)
tree996184047486e1484b3101e68ebc0b43b4ccf11e
parentfix: add test cases and test file basical operations (diff)
downloadGpgFrontend-566d5e41a34e08b06a5c84fd4ad9f944b6b31feb.tar.gz
GpgFrontend-566d5e41a34e08b06a5c84fd4ad9f944b6b31feb.zip
feat: avoid reading entire file to memory
-rw-r--r--src/core/function/gpg/GpgFileOpera.cpp296
-rw-r--r--src/core/function/gpg/GpgFileOpera.h63
-rw-r--r--src/core/model/GpgData.cpp32
-rw-r--r--src/core/model/GpgData.h22
-rw-r--r--src/test/core/GpgCoreTestFileBasicOpera.cpp16
-rw-r--r--src/ui/main_window/MainWindowFileSlotFunction.cpp93
6 files changed, 295 insertions, 227 deletions
diff --git a/src/core/function/gpg/GpgFileOpera.cpp b/src/core/function/gpg/GpgFileOpera.cpp
index 45286df2..7c247b95 100644
--- a/src/core/function/gpg/GpgFileOpera.cpp
+++ b/src/core/function/gpg/GpgFileOpera.cpp
@@ -31,120 +31,129 @@
#include "core/function/gpg/GpgBasicOperator.h"
#include "core/model/GFBuffer.h"
+#include "core/model/GpgData.h"
#include "core/model/GpgDecryptResult.h"
#include "core/model/GpgEncryptResult.h"
#include "core/model/GpgKey.h"
#include "core/model/GpgSignResult.h"
#include "core/model/GpgVerifyResult.h"
+#include "core/utils/AsyncUtils.h"
#include "core/utils/GpgUtils.h"
#include "core/utils/IOUtils.h"
namespace GpgFrontend {
+auto PathPreCheck(const std::filesystem::path& path, bool read)
+ -> std::tuple<bool, std::string> {
+ QFileInfo const file_info(path);
+ QFileInfo const path_info(file_info.absolutePath());
+
+ if (!path_info.exists()) {
+ return {false, _("")};
+ }
+ if (read ? !file_info.isReadable() : !path_info.isWritable()) {
+ return {false, _("")};
+ }
+ return {true, _("")};
+}
+
+GpgFileOpera::GpgFileOpera(int channel)
+ : SingletonFunctionObject<GpgFileOpera>(channel) {}
+
void GpgFileOpera::EncryptFile(std::vector<GpgKey> keys,
const std::filesystem::path& in_path, bool ascii,
const std::filesystem::path& out_path,
const GpgOperationCallback& cb) {
- auto read_result = ReadFileGFBuffer(in_path);
- if (!std::get<0>(read_result)) {
- throw std::runtime_error("read file error");
- }
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ std::vector<gpgme_key_t> recipients(keys.begin(), keys.end());
- GpgBasicOperator::GetInstance().Encrypt(
- std::move(keys), std::get<1>(read_result), ascii,
- [=](GpgError err, const DataObjectPtr& data_object) {
- if (!data_object->Check<GpgEncryptResult, GFBuffer>()) {
- throw std::runtime_error("data object transfers wrong arguments");
- }
- auto result = ExtractParams<GpgEncryptResult>(data_object, 0);
- auto buffer = ExtractParams<GFBuffer>(data_object, 1);
- if (CheckGpgError(err) == GPG_ERR_NO_ERROR) {
- if (!WriteFileGFBuffer(out_path, buffer)) {
- throw std::runtime_error("write buffer to file error");
- }
- }
- cb(err, TransferParams(result));
- });
+ // Last entry data_in array has to be nullptr
+ recipients.emplace_back(nullptr);
+
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = CheckGpgError(gpgme_op_encrypt(ctx, recipients.data(),
+ GPGME_ENCRYPT_ALWAYS_TRUST,
+ data_in, data_out));
+ data_object->Swap({GpgEncryptResult(gpgme_op_encrypt_result(ctx))});
+
+ return err;
+ },
+ cb, "gpgme_op_encrypt", "2.1.0");
}
void GpgFileOpera::DecryptFile(const std::filesystem::path& in_path,
const std::filesystem::path& out_path,
const GpgOperationCallback& cb) {
- auto read_result = ReadFileGFBuffer(in_path);
- if (!std::get<0>(read_result)) {
- throw std::runtime_error("read file error");
- }
-
- GpgBasicOperator::GetInstance().Decrypt(
- std::get<1>(read_result),
- [=](GpgError err, const DataObjectPtr& data_object) {
- if (!data_object->Check<GpgDecryptResult, GFBuffer>()) {
- throw std::runtime_error("data object transfers wrong arguments");
- }
- auto result = ExtractParams<GpgDecryptResult>(data_object, 0);
- auto buffer = ExtractParams<GFBuffer>(data_object, 1);
-
- if (CheckGpgError(err) == GPG_ERR_NO_ERROR &&
- !WriteFileGFBuffer(out_path, buffer)) {
- throw std::runtime_error("write buffer to file error");
- }
-
- cb(err, TransferParams(result));
- });
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ auto err = CheckGpgError(
+ gpgme_op_decrypt(ctx_.DefaultContext(), data_in, data_out));
+ data_object->Swap(
+ {GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext()))});
+
+ return err;
+ },
+ cb, "gpgme_op_decrypt", "2.1.0");
}
void GpgFileOpera::SignFile(KeyArgsList keys,
const std::filesystem::path& in_path, bool ascii,
const std::filesystem::path& out_path,
const GpgOperationCallback& cb) {
- auto read_result = ReadFileGFBuffer(in_path);
- if (!std::get<0>(read_result)) {
- throw std::runtime_error("read file error");
- }
-
- GpgBasicOperator::GetInstance().Sign(
- std::move(keys), std::get<1>(read_result), GPGME_SIG_MODE_DETACH, ascii,
- [=](GpgError err, const DataObjectPtr& data_object) {
- if (!data_object->Check<GpgSignResult, GFBuffer>()) {
- throw std::runtime_error("data object transfers wrong arguments");
- }
- auto result = ExtractParams<GpgSignResult>(data_object, 0);
- auto buffer = ExtractParams<GFBuffer>(data_object, 1);
-
- if (CheckGpgError(err) == GPG_ERR_NO_ERROR &&
- !WriteFileGFBuffer(out_path, buffer)) {
- throw std::runtime_error("write buffer to file error");
- }
- cb(err, TransferParams(result));
- });
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+
+ // Set Singers of this opera
+ GpgBasicOperator::GetInstance().SetSigners(keys, ascii);
+
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ err = CheckGpgError(
+ gpgme_op_sign(ctx, data_in, data_out, GPGME_SIG_MODE_DETACH));
+
+ data_object->Swap({
+ GpgSignResult(gpgme_op_sign_result(ctx)),
+ });
+ return err;
+ },
+ cb, "gpgme_op_sign", "2.1.0");
}
void GpgFileOpera::VerifyFile(const std::filesystem::path& data_path,
const std::filesystem::path& sign_path,
const GpgOperationCallback& cb) {
- auto read_result = ReadFileGFBuffer(data_path);
- if (!std::get<0>(read_result)) {
- throw std::runtime_error("read file error");
- }
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+
+ GpgData data_in(data_path, true);
+ GpgData data_out;
+ if (!sign_path.empty()) {
+ GpgData sig_data(sign_path, true);
+ err = CheckGpgError(gpgme_op_verify(ctx_.DefaultContext(), sig_data,
+ data_in, nullptr));
+ } else {
+ err = CheckGpgError(gpgme_op_verify(ctx_.DefaultContext(), data_in,
+ nullptr, data_out));
+ }
- GFBuffer sign_buffer;
- if (!sign_path.empty()) {
- auto read_result = ReadFileGFBuffer(sign_path);
- if (!std::get<0>(read_result)) {
- throw std::runtime_error("read file error");
- }
- sign_buffer = std::get<1>(read_result);
- }
+ data_object->Swap({
+ GpgVerifyResult(gpgme_op_verify_result(ctx_.DefaultContext())),
+ });
- GpgBasicOperator::GetInstance().Verify(
- std::get<1>(read_result), sign_buffer,
- [=](GpgError err, const DataObjectPtr& data_object) {
- if (!data_object->Check<GpgVerifyResult>()) {
- throw std::runtime_error("data object transfers wrong arguments");
- }
- auto result = ExtractParams<GpgVerifyResult>(data_object, 0);
- cb(err, TransferParams(result));
- });
+ return err;
+ },
+ cb, "gpgme_op_verify", "2.1.0");
}
void GpgFileOpera::EncryptSignFile(KeyArgsList keys, KeyArgsList signer_keys,
@@ -152,83 +161,74 @@ void GpgFileOpera::EncryptSignFile(KeyArgsList keys, KeyArgsList signer_keys,
bool ascii,
const std::filesystem::path& out_path,
const GpgOperationCallback& cb) {
- auto read_result = ReadFileGFBuffer(in_path);
- if (!std::get<0>(read_result)) {
- throw std::runtime_error("read file error");
- }
-
- GpgBasicOperator::GetInstance().EncryptSign(
- std::move(keys), std::move(signer_keys), std::get<1>(read_result), ascii,
- [=](GpgError err, const DataObjectPtr& data_object) {
- if (!data_object->Check<GpgEncryptResult, GpgSignResult, GFBuffer>()) {
- throw std::runtime_error("data object transfers wrong arguments");
- }
- auto encrypt_result = ExtractParams<GpgEncryptResult>(data_object, 0);
- auto sign_result = ExtractParams<GpgSignResult>(data_object, 1);
- auto buffer = ExtractParams<GFBuffer>(data_object, 2);
- if (CheckGpgError(err) == GPG_ERR_NO_ERROR) {
- if (!WriteFileGFBuffer(out_path, buffer)) {
- throw std::runtime_error("write buffer to file error");
- }
- }
- cb(err, TransferParams(encrypt_result, sign_result));
- });
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
+ std::vector<gpgme_key_t> recipients(keys.begin(), keys.end());
+
+ // Last entry data_in array has to be nullptr
+ recipients.emplace_back(nullptr);
+
+ GpgBasicOperator::GetInstance().SetSigners(signer_keys, ascii);
+
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ err = CheckGpgError(gpgme_op_encrypt_sign(ctx, recipients.data(),
+ GPGME_ENCRYPT_ALWAYS_TRUST,
+ data_in, data_out));
+
+ data_object->Swap({
+ GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ GpgSignResult(gpgme_op_sign_result(ctx)),
+ });
+ return err;
+ },
+ cb, "gpgme_op_encrypt_sign", "2.1.0");
}
void GpgFileOpera::DecryptVerifyFile(const std::filesystem::path& in_path,
const std::filesystem::path& out_path,
const GpgOperationCallback& cb) {
- auto read_result = ReadFileGFBuffer(in_path);
- if (!std::get<0>(read_result)) {
- throw std::runtime_error("read file error");
- }
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgError err;
- GpgBasicOperator::GetInstance().DecryptVerify(
- std::get<1>(read_result),
- [=](GpgError err, const DataObjectPtr& data_object) {
- if (!data_object
- ->Check<GpgDecryptResult, GpgVerifyResult, GFBuffer>()) {
- throw std::runtime_error("data object transfers wrong arguments");
- }
- auto decrypt_result = ExtractParams<GpgDecryptResult>(data_object, 0);
- auto verify_result = ExtractParams<GpgVerifyResult>(data_object, 1);
- auto buffer = ExtractParams<GFBuffer>(data_object, 2);
- if (CheckGpgError(err) == GPG_ERR_NO_ERROR) {
- if (!WriteFileGFBuffer(out_path, buffer)) {
- throw std::runtime_error("write buffer to file error");
- }
- }
- cb(err, TransferParams(decrypt_result, verify_result));
- });
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ err = CheckGpgError(
+ gpgme_op_decrypt_verify(ctx_.DefaultContext(), data_in, data_out));
+
+ data_object->Swap({
+ GpgDecryptResult(gpgme_op_decrypt_result(ctx_.DefaultContext())),
+ GpgVerifyResult(gpgme_op_verify_result(ctx_.DefaultContext())),
+ });
+
+ return err;
+ },
+ cb, "gpgme_op_decrypt_verify", "2.1.0");
}
+
void GpgFileOpera::EncryptFileSymmetric(const std::filesystem::path& in_path,
bool ascii,
const std::filesystem::path& out_path,
const GpgOperationCallback& cb) {
- auto read_result = ReadFileGFBuffer(in_path);
- if (!std::get<0>(read_result)) {
- throw std::runtime_error("read file error");
- }
-
- GpgBasicOperator::GetInstance().EncryptSymmetric(
- std::get<1>(read_result), ascii,
- [=](GpgError err, const DataObjectPtr& data_object) {
- if (!data_object->Check<GpgEncryptResult, GFBuffer>()) {
- throw std::runtime_error("data object transfers wrong arguments");
- }
- auto result = ExtractParams<GpgEncryptResult>(data_object, 0);
- auto buffer = ExtractParams<GFBuffer>(data_object, 1);
- if (CheckGpgError(err) != GPG_ERR_NO_ERROR) {
- cb(err, TransferParams(result));
- return;
- }
-
- if (!WriteFileGFBuffer(out_path, buffer)) {
- throw std::runtime_error("write buffer to file error");
- }
-
- cb(err, TransferParams(result));
- });
+ RunGpgOperaAsync(
+ [=](const DataObjectPtr& data_object) -> GpgError {
+ GpgData data_in(in_path, true);
+ GpgData data_out(out_path, false);
+
+ auto* ctx = ascii ? ctx_.DefaultContext() : ctx_.BinaryContext();
+ auto err = CheckGpgError(gpgme_op_encrypt(
+ ctx, nullptr, GPGME_ENCRYPT_SYMMETRIC, data_in, data_out));
+ data_object->Swap({
+ GpgEncryptResult(gpgme_op_encrypt_result(ctx)),
+ });
+
+ return err;
+ },
+ cb, "gpgme_op_encrypt_symmetric", "2.1.0");
}
-
} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/gpg/GpgFileOpera.h b/src/core/function/gpg/GpgFileOpera.h
index a358b60a..73649d47 100644
--- a/src/core/function/gpg/GpgFileOpera.h
+++ b/src/core/function/gpg/GpgFileOpera.h
@@ -28,6 +28,8 @@
#pragma once
+#include "core/function/basic/GpgFunctionObject.h"
+#include "core/function/gpg/GpgContext.h"
#include "core/function/result_analyse/GpgResultAnalyse.h"
#include "core/typedef/GpgTypedef.h"
@@ -38,9 +40,18 @@ namespace GpgFrontend {
*
* @class class: GpgBasicOperator
*/
-class GPGFRONTEND_CORE_EXPORT GpgFileOpera {
+class GPGFRONTEND_CORE_EXPORT GpgFileOpera
+ : public SingletonFunctionObject<GpgFileOpera> {
public:
/**
+ * @brief Construct a new Gpg File Opera object
+ *
+ * @param channel
+ */
+ explicit GpgFileOpera(
+ int channel = SingletonFunctionObject::GetDefaultChannel());
+
+ /**
* @brief Encrypted file with public key
*
* @param keys Used public key
@@ -50,10 +61,9 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera {
* @param channel Channel in context
* @return unsigned int error code
*/
- static void EncryptFile(KeyArgsList keys,
- const std::filesystem::path& in_path, bool ascii,
- const std::filesystem::path& out_path,
- const GpgOperationCallback& cb);
+ void EncryptFile(KeyArgsList keys, const std::filesystem::path& in_path,
+ bool ascii, const std::filesystem::path& out_path,
+ const GpgOperationCallback& cb);
/**
* @brief Encrypted file symmetrically (with password)
@@ -64,10 +74,9 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera {
* @param channel
* @return unsigned int
*/
- static void EncryptFileSymmetric(const std::filesystem::path& in_path,
- bool ascii,
- const std::filesystem::path& out_path,
- const GpgOperationCallback& cb);
+ void EncryptFileSymmetric(const std::filesystem::path& in_path, bool ascii,
+ const std::filesystem::path& out_path,
+ const GpgOperationCallback& cb);
/**
* @brief
@@ -77,9 +86,9 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera {
* @param result
* @return GpgError
*/
- static void DecryptFile(const std::filesystem::path& in_path,
- const std::filesystem::path& out_path,
- const GpgOperationCallback& cb);
+ void DecryptFile(const std::filesystem::path& in_path,
+ const std::filesystem::path& out_path,
+ const GpgOperationCallback& cb);
/**
* @brief Sign file with private key
@@ -91,9 +100,9 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera {
* @param channel
* @return GpgError
*/
- static void SignFile(KeyArgsList keys, const std::filesystem::path& in_path,
- bool ascii, const std::filesystem::path& out_path,
- const GpgOperationCallback& cb);
+ void SignFile(KeyArgsList keys, const std::filesystem::path& in_path,
+ bool ascii, const std::filesystem::path& out_path,
+ const GpgOperationCallback& cb);
/**
* @brief Verify file with public key
@@ -104,9 +113,9 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera {
* @param channel Channel in context
* @return GpgError
*/
- static void VerifyFile(const std::filesystem::path& data_path,
- const std::filesystem::path& sign_path,
- const GpgOperationCallback& cb);
+ void VerifyFile(const std::filesystem::path& data_path,
+ const std::filesystem::path& sign_path,
+ const GpgOperationCallback& cb);
/**
* @brief Encrypt and sign file with public key and private key
@@ -120,10 +129,10 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera {
* @param channel
* @return GpgError
*/
- static void EncryptSignFile(KeyArgsList keys, KeyArgsList signer_keys,
- const std::filesystem::path& in_path, bool ascii,
- const std::filesystem::path& out_path,
- const GpgOperationCallback& cb);
+ void EncryptSignFile(KeyArgsList keys, KeyArgsList signer_keys,
+ const std::filesystem::path& in_path, bool ascii,
+ const std::filesystem::path& out_path,
+ const GpgOperationCallback& cb);
/**
* @brief
@@ -134,9 +143,13 @@ class GPGFRONTEND_CORE_EXPORT GpgFileOpera {
* @param verify_res
* @return GpgError
*/
- static void DecryptVerifyFile(const std::filesystem::path& in_path,
- const std::filesystem::path& out_path,
- const GpgOperationCallback& cb);
+ void DecryptVerifyFile(const std::filesystem::path& in_path,
+ const std::filesystem::path& out_path,
+ const GpgOperationCallback& cb);
+
+ private:
+ GpgContext& ctx_ = GpgContext::GetInstance(
+ SingletonFunctionObject::GetChannel()); ///< Corresponding context
};
} // namespace GpgFrontend
diff --git a/src/core/model/GpgData.cpp b/src/core/model/GpgData.cpp
index 19f45e22..6a6105eb 100644
--- a/src/core/model/GpgData.cpp
+++ b/src/core/model/GpgData.cpp
@@ -28,6 +28,8 @@
#include "core/model/GpgData.h"
+#include <unistd.h>
+
#include "core/typedef/GpgTypedef.h"
namespace GpgFrontend {
@@ -63,6 +65,35 @@ GpgData::GpgData(const void* buffer, size_t size, bool copy) {
data_ref_ = std::unique_ptr<struct gpgme_data, DataRefDeleter>(data);
}
+GpgData::GpgData(int fd) : fd_(fd) {
+ gpgme_data_t data;
+
+ auto err = gpgme_data_new_from_fd(&data, fd);
+ assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR);
+
+ data_ref_ = std::unique_ptr<struct gpgme_data, DataRefDeleter>(data);
+}
+
+GpgData::GpgData(const std::filesystem::path& path, bool read) {
+ gpgme_data_t data;
+
+ fp_ = fopen(path.string().c_str(), read ? "rb" : "wb");
+ auto err = gpgme_data_new_from_stream(&data, fp_);
+ assert(gpgme_err_code(err) == GPG_ERR_NO_ERROR);
+
+ data_ref_ = std::unique_ptr<struct gpgme_data, DataRefDeleter>(data);
+}
+
+GpgData::~GpgData() {
+ if (fp_ != nullptr) {
+ fclose(fp_);
+ }
+
+ if (fd_ >= 0) {
+ close(fd_);
+ }
+}
+
auto GpgData::Read2Buffer() -> ByteArrayPtr {
gpgme_off_t ret = gpgme_data_seek(*this, 0, SEEK_SET);
ByteArrayPtr out_buffer = std::make_unique<std::string>();
@@ -110,5 +141,4 @@ auto GpgData::Read2GFBuffer() -> GFBuffer {
}
GpgData::operator gpgme_data_t() { return data_ref_.get(); }
-
} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/model/GpgData.h b/src/core/model/GpgData.h
index cd2e193e..4abde270 100644
--- a/src/core/model/GpgData.h
+++ b/src/core/model/GpgData.h
@@ -57,10 +57,30 @@ class GPGFRONTEND_CORE_EXPORT GpgData {
/**
* @brief Construct a new Gpg Data object
*
+ * @param fd
+ */
+ explicit GpgData(int fd);
+
+ /**
+ * @brief Construct a new Gpg Data object
+ *
+ * @param path
+ */
+ explicit GpgData(const std::filesystem::path& path, bool read);
+
+ /**
+ * @brief Construct a new Gpg Data object
+ *
*/
explicit GpgData(GFBuffer);
/**
+ * @brief Destroy the Gpg Data object
+ *
+ */
+ ~GpgData();
+
+ /**
* @brief
*
* @return gpgme_data_t
@@ -95,6 +115,8 @@ class GPGFRONTEND_CORE_EXPORT GpgData {
GFBuffer cached_buffer_;
std::unique_ptr<struct gpgme_data, DataRefDeleter> data_ref_ = nullptr; ///<
+ FILE* fp_ = nullptr;
+ int fd_ = -1;
};
} // namespace GpgFrontend
diff --git a/src/test/core/GpgCoreTestFileBasicOpera.cpp b/src/test/core/GpgCoreTestFileBasicOpera.cpp
index d07eae4f..029ff6fc 100644
--- a/src/test/core/GpgCoreTestFileBasicOpera.cpp
+++ b/src/test/core/GpgCoreTestFileBasicOpera.cpp
@@ -50,7 +50,7 @@ TEST_F(GpgCoreTest, CoreFileEncryptDecrTest) {
auto input_file = CreateTempFileAndWriteData("Hello GpgFrontend!");
auto output_file = GetTempFilePath();
- GpgFileOpera::EncryptFile(
+ GpgFileOpera::GetInstance().EncryptFile(
{encrypt_key}, input_file, true, output_file,
[output_file, &callback_called_flag](GpgError err,
const DataObjectPtr& data_obj) {
@@ -61,7 +61,7 @@ TEST_F(GpgCoreTest, CoreFileEncryptDecrTest) {
ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR);
auto decrpypt_output_file = GetTempFilePath();
- GpgFileOpera::DecryptFile(
+ GpgFileOpera::GetInstance().DecryptFile(
output_file, decrpypt_output_file,
[decrpypt_output_file, &callback_called_flag](
GpgError err, const DataObjectPtr& data_obj) {
@@ -95,7 +95,7 @@ TEST_F(GpgCoreTest, CoreFileEncryptSymmetricDecrTest) {
auto input_file = CreateTempFileAndWriteData("Hello GpgFrontend!");
auto output_file = GetTempFilePath();
- GpgFileOpera::EncryptFileSymmetric(
+ GpgFileOpera::GetInstance().EncryptFileSymmetric(
input_file, true, output_file,
[&callback_called_flag, output_file](GpgError err,
const DataObjectPtr& data_obj) {
@@ -105,7 +105,7 @@ TEST_F(GpgCoreTest, CoreFileEncryptSymmetricDecrTest) {
ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR);
auto decrpypt_output_file = GetTempFilePath();
- GpgFileOpera::DecryptFile(
+ GpgFileOpera::GetInstance().DecryptFile(
output_file, decrpypt_output_file,
[&callback_called_flag, decrpypt_output_file](
GpgError err, const DataObjectPtr& data_obj) {
@@ -142,7 +142,7 @@ TEST_F(GpgCoreTest, CoreFileSignVerifyNormalTest) {
auto input_file = CreateTempFileAndWriteData("Hello GpgFrontend!");
auto output_file = GetTempFilePath();
- GpgFileOpera::SignFile(
+ GpgFileOpera::GetInstance().SignFile(
{sign_key}, input_file, true, output_file,
[&callback_called_flag, input_file, output_file](
GpgError err, const DataObjectPtr& data_obj) {
@@ -151,7 +151,7 @@ TEST_F(GpgCoreTest, CoreFileSignVerifyNormalTest) {
ASSERT_TRUE(result.InvalidSigners().empty());
ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR);
- GpgFileOpera::VerifyFile(
+ GpgFileOpera::GetInstance().VerifyFile(
input_file, output_file,
[&callback_called_flag](GpgError err,
const DataObjectPtr& data_obj) {
@@ -187,7 +187,7 @@ TEST_F(GpgCoreTest, CoreFileEncryptSignDecrVerifyTest) {
ASSERT_TRUE(sign_key.IsPrivateKey());
ASSERT_TRUE(sign_key.IsHasActualSigningCapability());
- GpgFileOpera::EncryptSignFile(
+ GpgFileOpera::GetInstance().EncryptSignFile(
{encrypt_key}, {sign_key}, input_file, true, output_file,
[&callback_called_flag, output_file](GpgError err,
const DataObjectPtr& data_obj) {
@@ -199,7 +199,7 @@ TEST_F(GpgCoreTest, CoreFileEncryptSignDecrVerifyTest) {
ASSERT_EQ(CheckGpgError(err), GPG_ERR_NO_ERROR);
auto decrpypt_output_file = GetTempFilePath();
- GpgFileOpera::DecryptVerifyFile(
+ GpgFileOpera::GetInstance().DecryptVerifyFile(
output_file, decrpypt_output_file,
[&callback_called_flag, decrpypt_output_file](
GpgError err, const DataObjectPtr& data_obj) {
diff --git a/src/ui/main_window/MainWindowFileSlotFunction.cpp b/src/ui/main_window/MainWindowFileSlotFunction.cpp
index b46ef5f5..c4d8370a 100644
--- a/src/ui/main_window/MainWindowFileSlotFunction.cpp
+++ b/src/ui/main_window/MainWindowFileSlotFunction.cpp
@@ -108,7 +108,7 @@ auto ProcessTarballIntoDirectory(QWidget* parent,
if (if_error || !exists(target_path)) {
throw std::runtime_error("Decompress Failed");
}
- return {true, target_path.u8string()};
+ return {true, target_path.string()};
} catch (...) {
SPDLOG_ERROR("decompress error");
return {false, path};
@@ -122,11 +122,11 @@ auto ProcessTarballIntoDirectory(QWidget* parent,
* @param path the tarball to be converted
*/
auto ProcessDirectoryIntoTarball(QWidget* parent, std::filesystem::path path)
- -> bool {
+ -> std::tuple<bool, std::filesystem::path> {
try {
auto base_path = path.parent_path();
auto target_path = path;
- path = path.replace_extension("");
+ target_path = target_path.replace_extension("");
SPDLOG_DEBUG("base path: {} target archive path: {} selected_dir_path: {}",
base_path.u8string(), target_path.u8string(), path.u8string());
@@ -134,23 +134,24 @@ auto ProcessDirectoryIntoTarball(QWidget* parent, std::filesystem::path path)
bool if_error = false;
process_operation(parent, _("Making Tarball"), [&](DataObjectPtr) -> int {
try {
- GpgFrontend::ArchiveFileOperator::CreateArchive(base_path, target_path,
- 0, {path});
+ // GpgFrontend::ArchiveFileOperator::CreateArchive(base_path,
+ // target_path,
+ // 0, {path});
} catch (const std::runtime_error& e) {
if_error = true;
}
return 0;
});
- if (if_error || !exists(target_path)) {
- throw std::runtime_error("Compress Failed");
+ if (!exists(target_path)) {
+ return {false, ""};
}
- path = target_path.u8string().c_str();
+
+ return {if_error, target_path.replace_extension(".tar")};
} catch (...) {
- SPDLOG_ERROR("compress error");
- return false;
+ SPDLOG_ERROR("compress caught exception error");
+ return {false, ""};
}
- return true;
}
void MainWindow::SlotFileEncrypt() {
@@ -171,16 +172,13 @@ void MainWindow::SlotFileEncrypt() {
// get file info
QFileInfo const file_info(path);
- if (file_info.isDir()) {
- path = path.replace_extension(".tar");
- }
-
const auto* extension = ".asc";
if (non_ascii_when_export || file_info.isDir()) {
extension = ".gpg";
}
- auto out_path = path.replace_extension(path.extension().string() + extension);
+ auto out_path = path;
+ out_path = out_path.replace_extension(path.extension().string() + extension);
if (QFile::exists(out_path)) {
auto out_file_name = boost::format(_("The target file %1% already exists, "
"do you need to overwrite it?")) %
@@ -192,15 +190,6 @@ void MainWindow::SlotFileEncrypt() {
if (ret == QMessageBox::Cancel) return;
}
- if (file_info.isDir()) {
- // stop if the process making tarball failed
- if (!ProcessDirectoryIntoTarball(this, path)) {
- QMessageBox::critical(this, _("Error"),
- _("Unable to convert the folder into tarball."));
- return;
- }
- }
-
if (key_ids->empty()) {
// Symmetric Encrypt
auto ret = QMessageBox::information(
@@ -210,9 +199,22 @@ void MainWindow::SlotFileEncrypt() {
QMessageBox::Ok | QMessageBox::Cancel);
if (ret == QMessageBox::Cancel) return;
+ if (file_info.isDir()) {
+ // stop if the process making tarball failed
+ const auto [success, target_path] =
+ ProcessDirectoryIntoTarball(this, path);
+ if (!success) {
+ QMessageBox::critical(this, _("Error"),
+ _("Unable to convert the folder into tarball."));
+ return;
+ }
+ // reset target
+ path = target_path;
+ }
+
CommonUtils::WaitForOpera(
this, _("Symmetrically Encrypting"), [=](const OperaWaitingHd& op_hd) {
- GpgFileOpera::EncryptFileSymmetric(
+ GpgFileOpera::GetInstance().EncryptFileSymmetric(
path, !non_ascii_when_export, out_path,
[=](GpgError err, const DataObjectPtr& data_obj) {
// stop waiting
@@ -244,6 +246,7 @@ void MainWindow::SlotFileEncrypt() {
return;
}
+
auto p_keys = GpgKeyGetter::GetInstance().GetKeys(key_ids);
// check key abilities
@@ -262,7 +265,7 @@ void MainWindow::SlotFileEncrypt() {
CommonUtils::WaitForOpera(
this, _("Encrypting"), [=](const OperaWaitingHd& op_hd) {
- GpgFileOpera::EncryptFile(
+ GpgFileOpera::GetInstance().EncryptFile(
{p_keys->begin(), p_keys->end()}, path, !non_ascii_when_export,
out_path, [=](GpgError err, const DataObjectPtr& data_obj) {
// stop waiting
@@ -315,7 +318,7 @@ void MainWindow::SlotFileDecrypt() {
CommonUtils::WaitForOpera(
this, _("Decrypting"), [=](const OperaWaitingHd& op_hd) {
- GpgFileOpera::DecryptFile(
+ GpgFileOpera::GetInstance().DecryptFile(
path, out_path, [=](GpgError err, const DataObjectPtr& data_obj) {
// stop waiting
op_hd();
@@ -411,7 +414,7 @@ void MainWindow::SlotFileSign() {
CommonUtils::WaitForOpera(
this, _("Signing"), [=](const OperaWaitingHd& op_hd) {
- GpgFileOpera::EncryptFile(
+ GpgFileOpera::GetInstance().SignFile(
{keys->begin(), keys->end()}, path, !non_ascii_when_export,
sig_file_path, [=](GpgError err, const DataObjectPtr& data_obj) {
// stop waiting
@@ -433,27 +436,23 @@ void MainWindow::SlotFileSign() {
void MainWindow::SlotFileVerify() {
auto* file_tree_view = edit_->SlotCurPageFileTreeView();
- auto path = file_tree_view->GetSelected();
-
-#ifdef WINDOWS
- std::filesystem::path in_path = path.toStdU16String();
-#else
- std::filesystem::path in_path = path.toStdString();
-#endif
+ auto path_qstr = file_tree_view->GetSelected();
+ auto path = ConvertPathByOS(path_qstr);
+ if (!PathPreCheck(this, path)) return;
- std::filesystem::path sign_file_path = in_path;
+ std::filesystem::path sign_file_path = path;
std::filesystem::path data_file_path;
- if (in_path.extension() == ".gpg") {
+ if (path.extension() == ".gpg") {
swap(data_file_path, sign_file_path);
- } else if (in_path.extension() == ".sig" || in_path.extension() == ".asc") {
+ } else if (path.extension() == ".sig" || path.extension() == ".asc") {
data_file_path = sign_file_path.parent_path() / sign_file_path.stem();
}
SPDLOG_DEBUG("sign_file_path: {} {}", sign_file_path.u8string(),
sign_file_path.extension().u8string());
- if (in_path.extension() != ".gpg") {
+ if (path.extension() != ".gpg") {
bool ok;
QString const text = QInputDialog::getText(
this, _("Origin file to verify"), _("Filepath"), QLineEdit::Normal,
@@ -479,7 +478,7 @@ void MainWindow::SlotFileVerify() {
CommonUtils::WaitForOpera(
this, _("Verifying"), [=](const OperaWaitingHd& op_hd) {
- GpgFileOpera::DecryptFile(
+ GpgFileOpera::GetInstance().VerifyFile(
data_file_path.u8string(), sign_file_path.u8string(),
[=](GpgError err, const DataObjectPtr& data_obj) {
// stop waiting
@@ -552,7 +551,8 @@ void MainWindow::SlotFileEncryptSign() {
extension = ".gpg";
}
- auto out_path = path.replace_extension(path.extension().string() + extension);
+ auto out_path = path;
+ out_path = out_path.replace_extension(path.extension().string() + extension);
if (QFile::exists(out_path)) {
auto ret = QMessageBox::warning(
this, _("Warning"),
@@ -576,16 +576,19 @@ void MainWindow::SlotFileEncryptSign() {
// convert directory into tarball
if (file_info.isDir()) {
// stop if the process making tarball failed
- if (!ProcessDirectoryIntoTarball(this, path)) {
+ const auto [success, target_path] = ProcessDirectoryIntoTarball(this, path);
+ if (!success) {
QMessageBox::critical(this, _("Error"),
_("Unable to convert the folder into tarball."));
return;
}
+ // reset target
+ path = target_path;
}
CommonUtils::WaitForOpera(
this, _("Encrypting and Signing"), [=](const OperaWaitingHd& op_hd) {
- GpgFileOpera::EncryptSignFile(
+ GpgFileOpera::GetInstance().EncryptSignFile(
{p_keys->begin(), p_keys->end()},
{p_signer_keys->begin(), p_signer_keys->end()}, path,
!non_ascii_when_export, out_path,
@@ -652,7 +655,7 @@ void MainWindow::SlotFileDecryptVerify() {
CommonUtils::WaitForOpera(
this, _("Decrypting and Verifying"), [=](const OperaWaitingHd& op_hd) {
- GpgFileOpera::DecryptVerifyFile(
+ GpgFileOpera::GetInstance().DecryptVerifyFile(
path, out_path, [=](GpgError err, const DataObjectPtr& data_obj) {
// stop waiting
op_hd();