mirror of
				https://github.com/QRouland/UTPass.git
				synced 2025-10-31 08:36:31 +00:00 
			
		
		
		
	First draft Rewrite get all key with rnp
This commit is contained in:
		| @@ -12,6 +12,7 @@ dependencies_target: | |||||||
| - libquazip5-dev | - libquazip5-dev | ||||||
| - libgpgmepp-dev | - libgpgmepp-dev | ||||||
| - libgpgme-dev | - libgpgme-dev | ||||||
|  | - libjson-c-dev | ||||||
| - gpg | - gpg | ||||||
|  |  | ||||||
| libraries: | libraries: | ||||||
|   | |||||||
							
								
								
									
										127
									
								
								cmake/FindJSON-C.cmake
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								cmake/FindJSON-C.cmake
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,127 @@ | |||||||
|  | # Copyright (c) 2018, 2024 Ribose Inc. | ||||||
|  | # All rights reserved. | ||||||
|  | # | ||||||
|  | # Redistribution and use in source and binary forms, with or without | ||||||
|  | # modification, are permitted provided that the following conditions | ||||||
|  | # are met: | ||||||
|  | # 1. Redistributions of source code must retain the above copyright | ||||||
|  | #    notice, this list of conditions and the following disclaimer. | ||||||
|  | # 2. Redistributions in binary form must reproduce the above copyright | ||||||
|  | #    notice, this list of conditions and the following disclaimer in the | ||||||
|  | #    documentation and/or other materials provided with the distribution. | ||||||
|  | # | ||||||
|  | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||||
|  | # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | ||||||
|  | # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||||||
|  | # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS | ||||||
|  | # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||||||
|  | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||||||
|  | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||||||
|  | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||||||
|  | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||||||
|  | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||||||
|  | # POSSIBILITY OF SUCH DAMAGE. | ||||||
|  |  | ||||||
|  | #.rst: | ||||||
|  | # FindJSON-C | ||||||
|  | # ----------- | ||||||
|  | # | ||||||
|  | # Find the json-c library. | ||||||
|  | # | ||||||
|  | # IMPORTED Targets | ||||||
|  | # ^^^^^^^^^^^^^^^^ | ||||||
|  | # | ||||||
|  | # This module defines :prop_tgt:`IMPORTED` targets: | ||||||
|  | # | ||||||
|  | # ``JSON-C::JSON-C`` | ||||||
|  | #   The json-c library, if found. | ||||||
|  | # | ||||||
|  | # Result variables | ||||||
|  | # ^^^^^^^^^^^^^^^^ | ||||||
|  | # | ||||||
|  | # This module defines the following variables: | ||||||
|  | # | ||||||
|  | # :: | ||||||
|  | # | ||||||
|  | #   JSON-C_FOUND          - true if the headers and library were found | ||||||
|  | #   JSON-C_INCLUDE_DIRS   - where to find headers | ||||||
|  | #   JSON-C_LIBRARIES      - list of libraries to link | ||||||
|  | #   JSON-C_VERSION        - library version that was found, if any | ||||||
|  |  | ||||||
|  | # use pkg-config to get the directories and then use these values | ||||||
|  | # in the find_path() and find_library() calls | ||||||
|  | find_package(PkgConfig) | ||||||
|  | pkg_check_modules(PC_JSON-C QUIET json-c) | ||||||
|  |  | ||||||
|  | # RHEL-based systems may have json-c12 | ||||||
|  | if (NOT PC_JSON-C_FOUND) | ||||||
|  |   pkg_check_modules(PC_JSON-C QUIET json-c12) | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | # ..or even json-c13, accompanied by non-develop json-c (RHEL 8 ubi) | ||||||
|  | if (NOT PC_JSON-C_FOUND) | ||||||
|  |   pkg_check_modules(PC_JSON-C QUIET json-c13) | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | # find the headers | ||||||
|  | find_path(JSON-C_INCLUDE_DIR | ||||||
|  |   NAMES json_c_version.h | ||||||
|  |   HINTS | ||||||
|  |     ${PC_JSON-C_INCLUDEDIR} | ||||||
|  |     ${PC_JSON-C_INCLUDE_DIRS} | ||||||
|  |   PATH_SUFFIXES json-c json-c12 json-c13 | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | # find the library | ||||||
|  | find_library(JSON-C_LIBRARY | ||||||
|  |   NAMES json-c libjson-c json-c12 libjson-c12 json-c13 libjson-c13 | ||||||
|  |   HINTS | ||||||
|  |     ${PC_JSON-C_LIBDIR} | ||||||
|  |     ${PC_JSON-C_LIBRARY_DIRS} | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | # determine the version | ||||||
|  | if(PC_JSON-C_VERSION) | ||||||
|  |     set(JSON-C_VERSION ${PC_JSON-C_VERSION}) | ||||||
|  | elseif(JSON-C_INCLUDE_DIR AND EXISTS "${JSON-C_INCLUDE_DIR}/json_c_version.h") | ||||||
|  |     file(STRINGS "${JSON-C_INCLUDE_DIR}/json_c_version.h" _json-c_version_h | ||||||
|  |       REGEX "^#define[\t ]+JSON_C_VERSION[\t ]+\"[^\"]*\"$") | ||||||
|  |  | ||||||
|  |     string(REGEX REPLACE ".*#define[\t ]+JSON_C_VERSION[\t ]+\"([^\"]*)\".*" | ||||||
|  |       "\\1" _json-c_version_str "${_json-c_version_h}") | ||||||
|  |     set(JSON-C_VERSION "${_json-c_version_str}" | ||||||
|  |                        CACHE INTERNAL "The version of json-c which was detected") | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | include(FindPackageHandleStandardArgs) | ||||||
|  | find_package_handle_standard_args(JSON-C | ||||||
|  |   REQUIRED_VARS JSON-C_LIBRARY JSON-C_INCLUDE_DIR JSON-C_VERSION | ||||||
|  |   VERSION_VAR JSON-C_VERSION | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | if (JSON-C_FOUND) | ||||||
|  |   set(JSON-C_INCLUDE_DIRS ${JSON-C_INCLUDE_DIR} ${PC_JSON-C_INCLUDE_DIRS}) | ||||||
|  |   set(JSON-C_LIBRARIES ${JSON-C_LIBRARY}) | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | if (JSON-C_FOUND AND NOT TARGET JSON-C::JSON-C) | ||||||
|  |   # create the new library target | ||||||
|  |   add_library(JSON-C::JSON-C UNKNOWN IMPORTED) | ||||||
|  |   # set the required include dirs for the target | ||||||
|  |   if (JSON-C_INCLUDE_DIRS) | ||||||
|  |     set_target_properties(JSON-C::JSON-C | ||||||
|  |       PROPERTIES | ||||||
|  |         INTERFACE_INCLUDE_DIRECTORIES "${JSON-C_INCLUDE_DIRS}" | ||||||
|  |     ) | ||||||
|  |   endif() | ||||||
|  |   # set the required libraries for the target | ||||||
|  |   if (EXISTS "${JSON-C_LIBRARY}") | ||||||
|  |     set_target_properties(JSON-C::JSON-C | ||||||
|  |       PROPERTIES | ||||||
|  |         IMPORTED_LINK_INTERFACE_LANGUAGES "C" | ||||||
|  |         IMPORTED_LOCATION "${JSON-C_LIBRARY}" | ||||||
|  |     ) | ||||||
|  |   endif() | ||||||
|  | endif() | ||||||
|  |  | ||||||
|  | mark_as_advanced(JSON-C_INCLUDE_DIR JSON-C_LIBRARY) | ||||||
| @@ -8,6 +8,7 @@ set( | |||||||
|         passkeymodel.h |         passkeymodel.h | ||||||
|         jobs/rmjob.cpp |         jobs/rmjob.cpp | ||||||
|         jobs/rnpjob.cpp |         jobs/rnpjob.cpp | ||||||
|  |         jobs/getkeysjob.cpp | ||||||
|         jobs/importkeyjob.cpp |         jobs/importkeyjob.cpp | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -32,6 +33,7 @@ qt5_use_modules(${PLUGIN} Qml Quick DBus) | |||||||
| set(RNP_BUILD_DIR "${CMAKE_SOURCE_DIR}/build/${ARCH_TRIPLET}/rnp/install") | set(RNP_BUILD_DIR "${CMAKE_SOURCE_DIR}/build/${ARCH_TRIPLET}/rnp/install") | ||||||
|  |  | ||||||
| find_package(OpenSSL REQUIRED) | find_package(OpenSSL REQUIRED) | ||||||
|  | find_package(JSON-C 0.11) | ||||||
|  |  | ||||||
| INCLUDE_DIRECTORIES(${RNP_BUILD_DIR}/include) | INCLUDE_DIRECTORIES(${RNP_BUILD_DIR}/include) | ||||||
|  |  | ||||||
| @@ -57,7 +59,7 @@ add_library(libqgpgme SHARED IMPORTED) | |||||||
| set_property(TARGET libqgpgme PROPERTY IMPORTED_LOCATION "/usr/lib/${ARCH_TRIPLET}/libqgpgme.so") | set_property(TARGET libqgpgme PROPERTY IMPORTED_LOCATION "/usr/lib/${ARCH_TRIPLET}/libqgpgme.so") | ||||||
|  |  | ||||||
|  |  | ||||||
| target_link_libraries(${PLUGIN} rnp sexpp gpgerror libassuan libgpgme libgpgmepp libqgpgme OpenSSL::Crypto) | target_link_libraries(${PLUGIN} rnp sexpp gpgerror libassuan libgpgme libgpgmepp libqgpgme OpenSSL::Crypto JSON-C::JSON-C) | ||||||
|  |  | ||||||
| set(QT_IMPORTS_DIR "/lib/${ARCH_TRIPLET}") | set(QT_IMPORTS_DIR "/lib/${ARCH_TRIPLET}") | ||||||
| install(TARGETS ${PLUGIN} DESTINATION ${QT_IMPORTS_DIR}/${PLUGIN}/) | install(TARGETS ${PLUGIN} DESTINATION ${QT_IMPORTS_DIR}/${PLUGIN}/) | ||||||
|   | |||||||
							
								
								
									
										29
									
								
								plugins/Pass/jobs/getkeysjob.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								plugins/Pass/jobs/getkeysjob.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | |||||||
|  | #include <QDebug> | ||||||
|  | #include "getkeysjob.h" | ||||||
|  | #include <QJsonDocument> | ||||||
|  | #include <QJsonObject> | ||||||
|  | extern "C" { | ||||||
|  | #include <rnp/rnp.h> | ||||||
|  | #include <rnp/rnp_err.h> | ||||||
|  | } | ||||||
|  |  | ||||||
|  | GetKeysJob::GetKeysJob(QDir rnp_homedir): | ||||||
|  |     RnpJob(rnp_homedir) | ||||||
|  | { | ||||||
|  |     this->setObjectName("GetKeysJob"); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void GetKeysJob::run() | ||||||
|  | { | ||||||
|  |     qDebug() << "[GetKeysJob] Starting"; | ||||||
|  |  | ||||||
|  |     // Loading keyring | ||||||
|  |     QSet<QString> fingerprints = QSet<QString>(); | ||||||
|  |     this->load_full_keyring(&fingerprints); | ||||||
|  |  | ||||||
|  |     //Get all infos keys | ||||||
|  |     emit resultSuccess(fingerprints); | ||||||
|  |     qDebug() << "[GetKeysJob] Finished Successfully "; | ||||||
|  | } | ||||||
							
								
								
									
										38
									
								
								plugins/Pass/jobs/getkeysjob.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								plugins/Pass/jobs/getkeysjob.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | |||||||
|  | #ifndef GETKEYSJOB_H | ||||||
|  | #define GETKEYSJOB_H | ||||||
|  |  | ||||||
|  | #include <QJsonDocument> | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #include "rnpjob.h" | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @class GetKeysJob | ||||||
|  |  * @brief A class to handle get all gpg keys from rings in a separate thread. | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | class GetKeysJob : public RnpJob | ||||||
|  | { | ||||||
|  |     Q_OBJECT | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @brief The main function that performs the get all keys operation. | ||||||
|  |      * | ||||||
|  |      * Handles the process of removing recursively a target path. | ||||||
|  |      */ | ||||||
|  |     void run() override; | ||||||
|  |  | ||||||
|  | signals: | ||||||
|  |     void resultError(const rnp_result_t err); | ||||||
|  |     void resultSuccess(const QSet<QString> result); | ||||||
|  |  | ||||||
|  | public: | ||||||
|  |     /** | ||||||
|  |      * @brief Constructor for the GetKeysJob class. | ||||||
|  |      * | ||||||
|  |      * @param rnp_homedir Rnp home dir that contains the keyrings. | ||||||
|  |      */ | ||||||
|  |     GetKeysJob(QDir rnp_homedir); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #endif // GETKEYSJOB_H | ||||||
| @@ -1,5 +1,8 @@ | |||||||
| #include <QDebug> | #include <QDebug> | ||||||
|  | #include <QString> | ||||||
|  | #include <QJsonDocument> | ||||||
| #include "importkeyjob.h" | #include "importkeyjob.h" | ||||||
|  |  | ||||||
| extern "C" { | extern "C" { | ||||||
| #include <rnp/rnp.h> | #include <rnp/rnp.h> | ||||||
| #include <rnp/rnp_err.h> | #include <rnp/rnp_err.h> | ||||||
| @@ -9,38 +12,52 @@ ImportKeyJob::ImportKeyJob(QDir rnp_homedir, QString key_file_path): | |||||||
|     RnpJob(rnp_homedir), |     RnpJob(rnp_homedir), | ||||||
|     m_key_file_path(key_file_path) |     m_key_file_path(key_file_path) | ||||||
| { | { | ||||||
|     this->setObjectName("DecryptJob"); |     this->setObjectName("ImportKeyJob"); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| void ImportKeyJob::run() | void ImportKeyJob::run() | ||||||
| { | { | ||||||
|     qDebug() << "ImportKeyJob Starting  "; |     qDebug() << "[ImportKeyJob] Starting"; | ||||||
|     rnp_input_t input = NULL; |     rnp_input_t input = NULL; | ||||||
|     auto ret = rnp_input_from_path(&input, this->m_key_file_path.toLocal8Bit().constData()); |     auto ret = rnp_input_from_path(&input, this->m_key_file_path.toLocal8Bit().constData()); | ||||||
|     if(ret == RNP_SUCCESS) { |     if (ret == RNP_SUCCESS) { | ||||||
|         ret = rnp_load_keys(this->m_ffi, |         char *r = NULL; | ||||||
|                   "GPG", |         ret = rnp_import_keys(this->m_ffi, | ||||||
|                   input, |                               input, | ||||||
|                   RNP_LOAD_SAVE_PUBLIC_KEYS | RNP_LOAD_SAVE_SECRET_KEYS); |                               RNP_LOAD_SAVE_PUBLIC_KEYS | RNP_LOAD_SAVE_SECRET_KEYS, | ||||||
|  |                               &r); | ||||||
|  |  | ||||||
|  |         qDebug() << "[ImportKeyJob]" << QJsonDocument::fromJson(r); | ||||||
|  |         rnp_buffer_destroy(r); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     rnp_input_destroy(input); |     rnp_input_destroy(input); | ||||||
|     terminateWithError(ret); |     terminateOnError(ret); | ||||||
|  |  | ||||||
|     rnp_output_t output = NULL; |     rnp_output_t output = NULL; | ||||||
|     ret = rnp_output_to_file(&output, this->pubringPath().toLocal8Bit().constData(), RNP_OUTPUT_FILE_RANDOM); |     qDebug() << "[ImportKeyJob] Writing pubring to " << this->pubringPath(); | ||||||
|     if(ret == RNP_SUCCESS) { |     ret = rnp_output_to_file(&output, this->pubringPath().toLocal8Bit().constData(), RNP_OUTPUT_FILE_OVERWRITE); | ||||||
|         ret = rnp_save_keys(this->m_ffi, RNP_KEYSTORE_GPG, output, RNP_LOAD_SAVE_SECRET_KEYS); |     if (ret == RNP_SUCCESS) { | ||||||
|     } |         qDebug() << "[ImportKeyJob] Saving key pubring "; | ||||||
|     rnp_output_destroy(output); |         ret = rnp_save_keys(this->m_ffi, RNP_KEYSTORE_GPG, output, RNP_LOAD_SAVE_PUBLIC_KEYS); | ||||||
|     terminateWithError(ret); |  | ||||||
|  |  | ||||||
|     ret = rnp_output_to_file(&output, this->secringPath().toLocal8Bit().constData(), RNP_OUTPUT_FILE_OVERWRITE); |     } | ||||||
|     if(ret == RNP_SUCCESS) { |     if (ret == RNP_SUCCESS) { | ||||||
|         ret = rnp_save_keys(this->m_ffi, RNP_KEYSTORE_GPG, output, RNP_LOAD_SAVE_SECRET_KEYS); |         ret = rnp_output_finish(output); | ||||||
|     } |     } | ||||||
|     rnp_output_destroy(output); |     rnp_output_destroy(output); | ||||||
|     terminateWithError(ret); |     terminateOnError(ret); | ||||||
|  |  | ||||||
|  |     qDebug() << "[ImportKeyJob] Writing secring to " << this->secringPath(); | ||||||
|  |     ret = rnp_output_to_file(&output, this->secringPath().toLocal8Bit().constData(), RNP_OUTPUT_FILE_OVERWRITE); | ||||||
|  |     if (ret == RNP_SUCCESS) { | ||||||
|  |         qDebug() << "[ImportKeyJob] Saving key secring "; | ||||||
|  |         ret = rnp_save_keys(this->m_ffi, RNP_KEYSTORE_GPG, output, RNP_LOAD_SAVE_SECRET_KEYS); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     rnp_output_destroy(output); | ||||||
|  |     terminateOnError(ret); | ||||||
|     emit resultSuccess(); |     emit resultSuccess(); | ||||||
|     qDebug() << "ImportKeyJob Finished Successfully "; |     qDebug() << "[ImportKeyJob] Finished Successfully "; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -20,19 +20,22 @@ class ImportKeyJob : public RnpJob | |||||||
|      */ |      */ | ||||||
|     void run() override; |     void run() override; | ||||||
|  |  | ||||||
|  | signals: | ||||||
|  |     void resultSuccess(); | ||||||
|  |  | ||||||
| private: | private: | ||||||
|     QString m_key_file_path; ///< The path of the key file to import. |     QString m_key_file_path; ///< The path of the key file to import. | ||||||
|  |  | ||||||
| public: | public: | ||||||
|     /** |     /** | ||||||
|      * @brief Constructor for the RmJob class. |      * @brief Constructor for the ImportKeyJob class. | ||||||
|      * |      * | ||||||
|      * Initializes the ImportKeyJob with the file to import. |      * Initializes the ImportKeyJob with the file to import. | ||||||
|      * |      * | ||||||
|  |      * @param rnp_homedir Rnp home dir that contains the keyrings. | ||||||
|      * @param path Path of the key file to import. |      * @param path Path of the key file to import. | ||||||
|      */ |      */ | ||||||
|     ImportKeyJob(QDir rnp_homedir, QString key_file_path); |     ImportKeyJob(QDir rnp_homedir, QString path); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif // IMPORTKEYJOB_H | #endif // IMPORTKEYJOB_H | ||||||
|   | |||||||
| @@ -1,5 +1,8 @@ | |||||||
| #include <QDebug> | #include <QDebug> | ||||||
|  | #include <QJsonDocument> | ||||||
|  | #include <QJsonObject> | ||||||
|  | #include <QSet> | ||||||
|  | #include "qjsonarray.h" | ||||||
| #include "rnpjob.h" | #include "rnpjob.h" | ||||||
| extern "C" { | extern "C" { | ||||||
| #include <rnp/rnp.h> | #include <rnp/rnp.h> | ||||||
| @@ -9,29 +12,34 @@ extern "C" { | |||||||
| RnpJob::RnpJob(QDir rnp_homedir): | RnpJob::RnpJob(QDir rnp_homedir): | ||||||
|     m_rnp_homedir(rnp_homedir) |     m_rnp_homedir(rnp_homedir) | ||||||
| { | { | ||||||
|  |     qRegisterMetaType<rnp_result_t>("rnp_result_t"); | ||||||
|  |     qRegisterMetaType<QSet<QString >> ("QSet<QString>"); | ||||||
|  |  | ||||||
|  |  | ||||||
|     auto ret = rnp_ffi_create(&this->m_ffi, |     auto ret = rnp_ffi_create(&this->m_ffi, | ||||||
|                    RNP_KEYSTORE_GPG, |                               RNP_KEYSTORE_GPG, | ||||||
|                    RNP_KEYSTORE_GPG); |                               RNP_KEYSTORE_GPG); | ||||||
|     if(ret != RNP_SUCCESS) { |     if(ret != RNP_SUCCESS) { | ||||||
|         qDebug() << "Err : " << ret; |         qDebug() << "[RnpJob] Err : " << ret; | ||||||
|         qFatal("Error on rnp ffi init!"); |         qFatal("Error on rnp ffi init!"); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| RnpJob::~RnpJob(){ | RnpJob::~RnpJob() | ||||||
|  | { | ||||||
|     auto ret = rnp_ffi_destroy(this->m_ffi); |     auto ret = rnp_ffi_destroy(this->m_ffi); | ||||||
|     if(ret != RNP_SUCCESS) { |     if(ret != RNP_SUCCESS) { | ||||||
|         qDebug() << "Err : " << ret; |         qDebug() << "[RnpJob] Err : " << ret; | ||||||
|         qFatal("Something go wrong on rnp ffi detroy"); |         qFatal("Something go wrong on rnp ffi detroy"); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| bool RnpJob::passProvider(rnp_ffi_t        ffi, | bool RnpJob::passProvider(rnp_ffi_t        ffi, | ||||||
|                       void *           app_ctx, |                           void            *app_ctx, | ||||||
|                       rnp_key_handle_t key, |                           rnp_key_handle_t key, | ||||||
|                       const char *     pgp_context, |                           const char      *pgp_context, | ||||||
|                       char             buf[], |                           char             buf[], | ||||||
|                       size_t           buf_len) |                           size_t           buf_len) | ||||||
| { | { | ||||||
|     if (strcmp(pgp_context, "protect")) { |     if (strcmp(pgp_context, "protect")) { | ||||||
|         return false; |         return false; | ||||||
| @@ -40,3 +48,56 @@ bool RnpJob::passProvider(rnp_ffi_t        ffi, | |||||||
|     strncpy(buf, "password", buf_len); |     strncpy(buf, "password", buf_len); | ||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void RnpJob::load_key_file(QSet<QString> *fingerprints, const QString path, const uint32_t flags) | ||||||
|  | { | ||||||
|  |     qDebug() << "[RnpJob] load keyring at" << path; | ||||||
|  |     rnp_input_t input = NULL; | ||||||
|  |     if (QFileInfo::exists(this->pubringPath())) { | ||||||
|  |         auto ret = rnp_input_from_path(&input, path.toLocal8Bit().constData()); | ||||||
|  |         char *json = NULL; | ||||||
|  |         if (ret == RNP_SUCCESS) { | ||||||
|  |             ret = rnp_import_keys(this->m_ffi, | ||||||
|  |                                   input, | ||||||
|  |                                   flags, | ||||||
|  |                                   &json); | ||||||
|  |             if (ret != RNP_SUCCESS) { | ||||||
|  |  | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         QJsonDocument json_document = QJsonDocument::fromJson(json); | ||||||
|  |         qDebug() << "[RnpJob] json" << json_document; | ||||||
|  |         foreach (const QJsonValue fingerprint,  json_document.object()["keys"].toArray()) { | ||||||
|  |             qDebug() << "[RnpJob] Add fingerprint" << fingerprint["fingerprint"].toString(); | ||||||
|  |             fingerprints->insert(fingerprint["fingerprint"].toString()); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         rnp_input_destroy(input); | ||||||
|  |         rnp_buffer_destroy(json); | ||||||
|  |         terminateOnError(ret); | ||||||
|  |         qDebug() << "[RnpJob] keyring loaded successfully"; | ||||||
|  |     } else { | ||||||
|  |         qDebug() << "[RnpJob] No keyring" << path << "not found"; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void RnpJob::load_pub_keyring(QSet<QString> *fingerprints) | ||||||
|  | { | ||||||
|  |     this->load_key_file(fingerprints, this->pubringPath(), RNP_LOAD_SAVE_PUBLIC_KEYS); | ||||||
|  |     qDebug() << "[RnpJob] pub fingerprints" << *fingerprints; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void RnpJob::load_sec_keyring(QSet<QString> *fingerprints) | ||||||
|  | { | ||||||
|  |     this->load_key_file(fingerprints, this->secringPath(),  RNP_LOAD_SAVE_SECRET_KEYS); | ||||||
|  |     qDebug() << "[RnpJob] sec fingerprints" << *fingerprints; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void RnpJob::load_full_keyring(QSet<QString> *fingerprints) | ||||||
|  | { | ||||||
|  |     this->load_pub_keyring(fingerprints); | ||||||
|  |     this->load_sec_keyring(fingerprints); | ||||||
|  |     qDebug() << "[RnpJob] full fingerprints" << *fingerprints; | ||||||
|  | } | ||||||
|   | |||||||
| @@ -9,10 +9,10 @@ extern "C" { | |||||||
| #include <variant> | #include <variant> | ||||||
|  |  | ||||||
|  |  | ||||||
| #define terminateWithError(ret)                              \ | #define terminateOnError(ret)                              \ | ||||||
| if(ret != RNP_SUCCESS) {                                        \ | if(ret != RNP_SUCCESS) {                                        \ | ||||||
|     qDebug() << "Err : " << ret;                                \ |     qDebug() << "[RnpJob] Err : " << ret;                                \ | ||||||
|     qDebug() << "Err Msg : " << rnp_result_to_string(ret);      \ |     qDebug() << "[RnpJob] Err Msg : " << rnp_result_to_string(ret);      \ | ||||||
|     emit resultError(ret);                                      \ |     emit resultError(ret);                                      \ | ||||||
|     return;                                                     \ |     return;                                                     \ | ||||||
| }                                                               \ | }                                                               \ | ||||||
| @@ -30,16 +30,16 @@ class RnpJob : public QThread | |||||||
|  |  | ||||||
| signals: | signals: | ||||||
|     void resultError(const rnp_result_t err); |     void resultError(const rnp_result_t err); | ||||||
|     void resultSuccess(); |  | ||||||
|  |  | ||||||
| private: | private: | ||||||
|     static bool passProvider(rnp_ffi_t        ffi, |     static bool passProvider(rnp_ffi_t        ffi, | ||||||
|                          void *           app_ctx, |                              void            *app_ctx, | ||||||
|                          rnp_key_handle_t key, |                              rnp_key_handle_t key, | ||||||
|                          const char *     pgp_context, |                              const char      *pgp_context, | ||||||
|                          char             buf[], |                              char             buf[], | ||||||
|                          size_t           buf_len); |                              size_t           buf_len); | ||||||
|     QDir m_rnp_homedir; ///< rmp ffi. |     QDir m_rnp_homedir; ///< rmp ffi. | ||||||
|  |     void load_key_file(QSet<QString> *fingerprints, const QString path, const uint32_t flags); | ||||||
|  |  | ||||||
| protected: | protected: | ||||||
|     rnp_ffi_t m_ffi; ///< rmp ffi. |     rnp_ffi_t m_ffi; ///< rmp ffi. | ||||||
| @@ -49,7 +49,8 @@ protected: | |||||||
|      * |      * | ||||||
|      * @return The path to public keys keyring |      * @return The path to public keys keyring | ||||||
|      */ |      */ | ||||||
|     QString pubringPath() { |     QString pubringPath() | ||||||
|  |     { | ||||||
|         return this->m_rnp_homedir.filePath("pubring.pgp"); |         return this->m_rnp_homedir.filePath("pubring.pgp"); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -58,16 +59,22 @@ protected: | |||||||
|      * |      * | ||||||
|      * @return The path to secret keys keyring |      * @return The path to secret keys keyring | ||||||
|      */ |      */ | ||||||
|     QString secringPath() { |     QString secringPath() | ||||||
|  |     { | ||||||
|         return this->m_rnp_homedir.filePath("secring.pgp"); |         return this->m_rnp_homedir.filePath("secring.pgp"); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     void load_sec_keyring(QSet<QString> *fingerprints); | ||||||
|  |     void load_pub_keyring(QSet<QString> *fingerprints); | ||||||
|  |     void load_full_keyring(QSet<QString> *fingerprints); | ||||||
|  |  | ||||||
| public: | public: | ||||||
|     /** |     /** | ||||||
|      * @brief Constructor for the RnpJob class. |      * @brief Constructor for the RnpJob class. | ||||||
|      * |      * | ||||||
|      * Initializes the RnpJob instance. |      * Initializes the RnpJob instance. | ||||||
|  |      * | ||||||
|  |      * @param rnp_homedir Rnp home dir that contains the keyrings. | ||||||
|      */ |      */ | ||||||
|     RnpJob(QDir rnp_homedir); |     RnpJob(QDir rnp_homedir); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ | |||||||
| #include <QtCore/QStandardPaths> | #include <QtCore/QStandardPaths> | ||||||
| #include <QtCore/QDir> | #include <QtCore/QDir> | ||||||
|  |  | ||||||
|  | #include "jobs/getkeysjob.h" | ||||||
| #include "jobs/importkeyjob.h" | #include "jobs/importkeyjob.h" | ||||||
| #include "pass.h" | #include "pass.h" | ||||||
|  |  | ||||||
| @@ -11,33 +12,46 @@ Pass::Pass(): | |||||||
|     m_password_store (QStandardPaths::writableLocation( |     m_password_store (QStandardPaths::writableLocation( | ||||||
|                           QStandardPaths::AppDataLocation).append("/.password-store")), |                           QStandardPaths::AppDataLocation).append("/.password-store")), | ||||||
|     m_gpg_home (QStandardPaths::writableLocation( |     m_gpg_home (QStandardPaths::writableLocation( | ||||||
|                      QStandardPaths::AppDataLocation).append("/.rnp")), |                     QStandardPaths::AppDataLocation).append("/.rnp")), | ||||||
|     m_sem(std::unique_ptr<QSemaphore>(new QSemaphore(1))), |     m_sem(std::unique_ptr<QSemaphore>(new QSemaphore(1))), | ||||||
|     m_show_filename(QString()) |     m_show_filename(QString()) | ||||||
| { | { | ||||||
|     qRegisterMetaType<rnp_result_t>("rnp_result_t"); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void Pass::initialize(QObject *window) | void Pass::initialize(QObject *window) | ||||||
| { | { | ||||||
|     if (!window) { |     if (!window) { | ||||||
|         qWarning("Window should not be null unless your in testing"); |         qWarning("[Pass] Window should be null only for testing"); | ||||||
|     } |     } | ||||||
|  |     this->initGpgHome(); | ||||||
|  |     this->initPasswordStore(); | ||||||
|  | } | ||||||
|  |  | ||||||
|     // this->m_gpg = std::unique_ptr<Gpg>(new Gpg(window)); |  | ||||||
|     // UTPassphraseProvider *passphrase_provider = dynamic_cast<UTPassphraseProvider*>(this->m_gpg->passphrase_provider()); |  | ||||||
|     // QObject::connect(this, &Pass::responsePassphraseDialogPropagate, passphrase_provider, |  | ||||||
|     //                  &UTPassphraseProvider::handleResponse); |  | ||||||
|  |  | ||||||
|     // QObject::connect(this->m_gpg.get(), &Gpg::getKeysResult, this, &Pass::getAllGPGKeysResult); | void Pass::initGpgHome() | ||||||
|     // QObject::connect(this->m_gpg.get(), &Gpg::deleteKeyResult, this, &Pass::deleteGPGKeyResult); | { | ||||||
|     // QObject::connect(this->m_gpg.get(), &Gpg::decryptResult, this, &Pass::showResult); |     // delete gpghome from previous version using GPGME | ||||||
|  |     QString path = QStandardPaths::writableLocation( | ||||||
|  |                        QStandardPaths::AppDataLocation).append("/.gpghome"); | ||||||
|  |     QDir dir(path); | ||||||
|  |     dir.removeRecursively(); | ||||||
|  |  | ||||||
|     QDir dir(m_password_store); |     // create gpghome for rnp | ||||||
|     if (!dir.exists()) { |     QDir dir_gpg_home(this->m_gpg_home); | ||||||
|         dir.mkpath("."); |     if (!dir_gpg_home.exists()) { | ||||||
|  |         dir_gpg_home.mkpath("."); | ||||||
|     } |     } | ||||||
|     qInfo() << "Password Store is :" << m_password_store; |     qInfo() << "[Pass] GPG Home is :" << m_gpg_home; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Pass::initPasswordStore() | ||||||
|  | { | ||||||
|  |     QDir dir_password_store(this->m_password_store); | ||||||
|  |     if (!dir_password_store.exists()) { | ||||||
|  |         dir_password_store.mkpath("."); | ||||||
|  |     } | ||||||
|  |     qInfo() << "[Pass] Password Store is :" << m_password_store; | ||||||
| } | } | ||||||
|  |  | ||||||
| // bool Pass::show(QUrl url) | // bool Pass::show(QUrl url) | ||||||
| @@ -125,9 +139,9 @@ void Pass::initialize(QObject *window) | |||||||
|  |  | ||||||
| bool Pass::importGPGKey(QUrl url) | bool Pass::importGPGKey(QUrl url) | ||||||
| { | { | ||||||
|     qInfo() << "Import GPG Key from " << url; |     qInfo() << "[Pass] Import GPG Key from " << url; | ||||||
|     if (!this->m_sem->tryAcquire(1, 500)) { |     if (!this->m_sem->tryAcquire(1, 500)) { | ||||||
|         qInfo() << "A job is already running"; |         qInfo() << "[Pass] A job is already running"; | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|     auto job = new ImportKeyJob(this->m_gpg_home, url.toLocalFile()); |     auto job = new ImportKeyJob(this->m_gpg_home, url.toLocalFile()); | ||||||
| @@ -140,26 +154,46 @@ bool Pass::importGPGKey(QUrl url) | |||||||
|  |  | ||||||
| void Pass::slotImportGPGKeyError(rnp_result_t err) | void Pass::slotImportGPGKeyError(rnp_result_t err) | ||||||
| { | { | ||||||
|     qDebug() << "Import GPG Key Failed"; |     qInfo() << "[Pass] Import GPG Key Failed"; | ||||||
|     emit importGPGKeyFailed(rnp_result_to_string(err)); |     emit importGPGKeyFailed(rnp_result_to_string(err)); | ||||||
|     this->m_sem->release(1); |     this->m_sem->release(1); | ||||||
| } | } | ||||||
|  |  | ||||||
| void Pass::slotImportGPGKeySucceed() | void Pass::slotImportGPGKeySucceed() | ||||||
| { | { | ||||||
|     qDebug() << "Import GPG Key Failed"; |     qInfo() << "[Pass] Import GPG Key Succesfull"; | ||||||
|     emit importGPGKeySucceed(); |     emit importGPGKeySucceed(); | ||||||
|     this->m_sem->release(1); |     this->m_sem->release(1); | ||||||
| } | } | ||||||
|  |  | ||||||
| // bool Pass::getAllGPGKeys() | bool Pass::getAllGPGKeys() | ||||||
| // { | { | ||||||
| //     if (!this->m_sem->tryAcquire(1, 500)) { |     qInfo() << "[Pass] Get all GPG Keys"; | ||||||
| //         return false; |     if (!this->m_sem->tryAcquire(1, 500)) { | ||||||
| //     } |         qInfo() << "[Pass] A job is already running"; | ||||||
| //     qInfo() << "Get GPG keys"; |         return false; | ||||||
| //     return this->m_gpg->getAllKeys(); |     } | ||||||
| // } |     auto job = new GetKeysJob(this->m_gpg_home); | ||||||
|  |     QObject::connect(job, &GetKeysJob::resultError, this, &Pass::slotGetAllGPGKeysError); | ||||||
|  |     QObject::connect(job, &GetKeysJob::resultSuccess, this, &Pass::slotGetAllGPGKeysSucceed); | ||||||
|  |     connect(job, &ImportKeyJob::finished, job, &QObject::deleteLater); | ||||||
|  |     job->start(); | ||||||
|  |     return true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Pass::slotGetAllGPGKeysError(rnp_result_t err) | ||||||
|  | { | ||||||
|  |     qInfo() << "[Pass] Get all GPG Keys Failed"; | ||||||
|  |     emit getAllGPGKeysFailed(rnp_result_to_string(err)); | ||||||
|  |     this->m_sem->release(1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Pass::slotGetAllGPGKeysSucceed(QSet<QString> result) | ||||||
|  | { | ||||||
|  |     qInfo() << "[Pass] Get all GPG Keys Succeed"; | ||||||
|  |     emit getAllGPGKeysSucceed(result.values()); | ||||||
|  |     this->m_sem->release(1); | ||||||
|  | } | ||||||
|  |  | ||||||
| // void Pass::getAllGPGKeysResult(Error err,  std::vector<GpgME::Key> keys_info) | // void Pass::getAllGPGKeysResult(Error err,  std::vector<GpgME::Key> keys_info) | ||||||
| // { | // { | ||||||
|   | |||||||
| @@ -49,15 +49,19 @@ private slots: | |||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * @brief Slot to handle the succeed result of a GPG key import operation. |      * @brief Slot to handle the succeed result of a GPG key import operation. | ||||||
|      * @param err The error that occurred during the operation. |  | ||||||
|      */ |      */ | ||||||
|     void slotImportGPGKeySucceed(); |     void slotImportGPGKeySucceed(); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * @brief Slot to handle the result of retrieving all GPG keys. |      * @brief Slot to handle the result of retrieving all GPG keys. | ||||||
|      * @param err The error that occurred during the operation. |      * @param err The error that occurred during the operation. | ||||||
|      * @param keys_info The list of GPG keys retrieved. |  | ||||||
|      */ |      */ | ||||||
|     void getAllGPGKeysResult(Error err, std::vector<GpgME::Key> keys_info); |     void slotGetAllGPGKeysError(rnp_result_t err); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @brief Slot to handle the succeed result of a GPG key get all keys operation. | ||||||
|  |      */ | ||||||
|  |     void slotGetAllGPGKeysSucceed(QSet<QString> result); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * @brief Slot to handle the result of a delete Password Store operation. |      * @brief Slot to handle the result of a delete Password Store operation. | ||||||
| @@ -93,7 +97,7 @@ signals: | |||||||
|      * @brief Emitted when all GPG keys are successfully retrieved. |      * @brief Emitted when all GPG keys are successfully retrieved. | ||||||
|      * @param keys_info The list of retrieved keys. |      * @param keys_info The list of retrieved keys. | ||||||
|      */ |      */ | ||||||
|     void getAllGPGKeysSucceed(QVariant keys_info); |     void getAllGPGKeysSucceed(QList<QString> keys_info); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * @brief Emitted when retrieving GPG keys fails. |      * @brief Emitted when retrieving GPG keys fails. | ||||||
| @@ -142,10 +146,21 @@ signals: | |||||||
| private: | private: | ||||||
|     QString m_password_store; /**< The path to the password store. */ |     QString m_password_store; /**< The path to the password store. */ | ||||||
|     QString m_gpg_home; /**< The path to the gpg home. */ |     QString m_gpg_home; /**< The path to the gpg home. */ | ||||||
|     PassphraseProvider* m_passphrase_provider; /**< Semaphore for managing concurrent operations. */ |     PassphraseProvider *m_passphrase_provider; /**< Semaphore for managing concurrent operations. */ | ||||||
|     std::unique_ptr<QSemaphore> m_sem; /**< Semaphore for managing concurrent operations. */ |     std::unique_ptr<QSemaphore> m_sem; /**< Semaphore for managing concurrent operations. */ | ||||||
|     QString m_show_filename; /**< The filename associated with the password to show. */ |     QString m_show_filename; /**< The filename associated with the password to show. */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @brief Initialize gpg home. | ||||||
|  |      */ | ||||||
|  |     void initGpgHome(); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @brief Initialize password store. | ||||||
|  |      */ | ||||||
|  |     void initPasswordStore(); | ||||||
|  |  | ||||||
| public: | public: | ||||||
|     /** |     /** | ||||||
|      * @brief Constructs the Pass object. |      * @brief Constructs the Pass object. | ||||||
| @@ -167,7 +182,7 @@ public: | |||||||
|      */ |      */ | ||||||
|     void set_password_store(QString password_store) |     void set_password_store(QString password_store) | ||||||
|     { |     { | ||||||
|         qInfo() << "Password Store changed to :" << password_store; |         qInfo() << "[Pass] Password Store changed to :" << password_store; | ||||||
|         this->m_password_store = password_store; |         this->m_password_store = password_store; | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
| @@ -186,7 +201,7 @@ public: | |||||||
|      */ |      */ | ||||||
|     void set_gpg_home(QString gpg_home) |     void set_gpg_home(QString gpg_home) | ||||||
|     { |     { | ||||||
|         qInfo() << "GNUPG Home changed to :" << gpg_home; |         qInfo() << "[Pass] GPG Home changed to :" << gpg_home; | ||||||
|         this->m_gpg_home = gpg_home; |         this->m_gpg_home = gpg_home; | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ msgid "" | |||||||
| msgstr "" | msgstr "" | ||||||
| "Project-Id-Version: utpass.qrouland\n" | "Project-Id-Version: utpass.qrouland\n" | ||||||
| "Report-Msgid-Bugs-To: \n" | "Report-Msgid-Bugs-To: \n" | ||||||
| "POT-Creation-Date: 2025-01-29 16:33+0100\n" | "POT-Creation-Date: 2025-01-30 16:16+0100\n" | ||||||
| "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" | ||||||
| "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | ||||||
| "Language-Team: LANGUAGE <LL@li.org>\n" | "Language-Team: LANGUAGE <LL@li.org>\n" | ||||||
|   | |||||||
| @@ -21,15 +21,13 @@ MainView { | |||||||
|         pop.activateFocus(); |         pop.activateFocus(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|     objectName: "mainView" |     objectName: "mainView" | ||||||
|     applicationName: "utpass.qrouland" |     applicationName: "utpass.qrouland" | ||||||
|     automaticOrientation: true |     automaticOrientation: true | ||||||
|     width: units.gu(45) |     width: units.gu(45) | ||||||
|     height: units.gu(75) |     height: units.gu(75) | ||||||
|  |  | ||||||
|     Component.onCompleted: { |     Component.onCompleted: { | ||||||
|         myWorker.sendMessage("Hello World !") |         myWorker.sendMessage("Hello World !"); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     PageStack { |     PageStack { | ||||||
|   | |||||||
| @@ -11,7 +11,6 @@ Dialog { | |||||||
|     signal validated() |     signal validated() | ||||||
|     signal canceled() |     signal canceled() | ||||||
|  |  | ||||||
|  |  | ||||||
|     Button { |     Button { | ||||||
|         id: continueButton |         id: continueButton | ||||||
|  |  | ||||||
|   | |||||||
| @@ -29,7 +29,6 @@ Page { | |||||||
|         anchors.rightMargin: units.gu(2) |         anchors.rightMargin: units.gu(2) | ||||||
|         spacing: units.gu(1) |         spacing: units.gu(1) | ||||||
|  |  | ||||||
|  |  | ||||||
|         Rectangle { |         Rectangle { | ||||||
|             width: parent.width |             width: parent.width | ||||||
|             height: units.gu(1) |             height: units.gu(1) | ||||||
|   | |||||||
| @@ -8,6 +8,7 @@ import QtQuick 2.4 | |||||||
|  |  | ||||||
| Page { | Page { | ||||||
|     id: infoKeysPage |     id: infoKeysPage | ||||||
|  |  | ||||||
|     property list<QtObject> __keys |     property list<QtObject> __keys | ||||||
|     property QtObject __currentKey |     property QtObject __currentKey | ||||||
|  |  | ||||||
| @@ -15,7 +16,7 @@ Page { | |||||||
|         Pass.getAllGPGKeysSucceed.connect(function(keys_info) { |         Pass.getAllGPGKeysSucceed.connect(function(keys_info) { | ||||||
|             infoKeysPage.__keys = keys_info; |             infoKeysPage.__keys = keys_info; | ||||||
|             for (var i = 0; i < keys_info.length; ++i) { |             for (var i = 0; i < keys_info.length; ++i) { | ||||||
|                 console.debug("is secret " + keys_info[i].isSecret) |                 console.debug("is secret " + keys_info[i].isSecret); | ||||||
|             } |             } | ||||||
|         }); |         }); | ||||||
|         Pass.getAllGPGKeysFailed.connect(function(message) { |         Pass.getAllGPGKeysFailed.connect(function(message) { | ||||||
| @@ -108,7 +109,6 @@ Page { | |||||||
|                         userIdsModel.append({ |                         userIdsModel.append({ | ||||||
|                             "model": model.modelData.userIds[i] |                             "model": model.modelData.userIds[i] | ||||||
|                         }); |                         }); | ||||||
|  |  | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|   | |||||||
							
								
								
									
										
											BIN
										
									
								
								tests/assets/gpghome/pubring.pgp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								tests/assets/gpghome/pubring.pgp
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								tests/assets/gpghome/secring.pgp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								tests/assets/gpghome/secring.pgp
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -7,13 +7,14 @@ | |||||||
|  |  | ||||||
| class TesTPassphraseProvider : public QObject, public GpgME::PassphraseProvider | class TesTPassphraseProvider : public QObject, public GpgME::PassphraseProvider | ||||||
| { | { | ||||||
| Q_OBJECT |     Q_OBJECT | ||||||
|  |  | ||||||
| public: | public: | ||||||
|     char *getPassphrase(const char *useridHint, |     char *getPassphrase(const char *useridHint, | ||||||
|                         const char *description, |                         const char *description, | ||||||
|                         bool previousWasBad, |                         bool previousWasBad, | ||||||
|                         bool &canceled) override { |                         bool &canceled) override | ||||||
|  |     { | ||||||
|  |  | ||||||
|         char *ret; |         char *ret; | ||||||
|         gpgrt_asprintf(&ret, "%s", "utpasspassphrase"); |         gpgrt_asprintf(&ret, "%s", "utpasspassphrase"); | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ | |||||||
| #include "utils.h" | #include "utils.h" | ||||||
|  |  | ||||||
| TestsUtils::TestsUtils(): | TestsUtils::TestsUtils(): | ||||||
| m_passphrase_povider(std::unique_ptr<TesTPassphraseProvider>(new TesTPassphraseProvider())) |     m_passphrase_povider(std::unique_ptr<TesTPassphraseProvider>(new TesTPassphraseProvider())) | ||||||
| {} | {} | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -28,12 +28,47 @@ QString TestsUtils::getTempPath() | |||||||
|     QDir dir; |     QDir dir; | ||||||
|     dir.mkpath(newTempDir); |     dir.mkpath(newTempDir); | ||||||
|  |  | ||||||
|     qDebug() << "TempDir : " << newTempDir; |     qDebug() << "[TestUtils] TempDir : " << newTempDir; | ||||||
|     return newTempDir; |     return newTempDir; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | bool TestsUtils::fileExists(QUrl path) | ||||||
|  | { | ||||||
|  |     QString p = path.toLocalFile(); | ||||||
|  |     auto ret = QFileInfo::exists(p) && QFileInfo(p).isFile(); | ||||||
|  |     qDebug() << "[TestUtils]" << p << "is existing file :" << ret; | ||||||
|  |     return ret; | ||||||
|  | } | ||||||
|  |  | ||||||
| QObject* TestsUtils::getTestPassphraseProvider() | void TestsUtils::copyFolder(QUrl sourceFolderUrl, QUrl destFolderUrl) | ||||||
|  | { | ||||||
|  |     auto sourceFolder = sourceFolderUrl.toLocalFile(); | ||||||
|  |     auto destFolder = destFolderUrl.toLocalFile(); | ||||||
|  |     QDir sourceDir(sourceFolder); | ||||||
|  |     if (!sourceDir.exists()) | ||||||
|  |         return; | ||||||
|  |     QDir destDir(destFolder); | ||||||
|  |     if (!destDir.exists()) { | ||||||
|  |         destDir.mkdir(destFolder); | ||||||
|  |     } | ||||||
|  |     qDebug() << "[TestUtils]" << "Copy files from" << sourceFolder << "to" << destFolder; | ||||||
|  |     QStringList files = sourceDir.entryList(QDir::Files); | ||||||
|  |     for (int i = 0; i < files.count(); i++) { | ||||||
|  |         QString srcName = sourceFolder + "/" + files[i]; | ||||||
|  |         QString destName = destFolder + "/" + files[i]; | ||||||
|  |         QFile::copy(srcName, destName); | ||||||
|  |         qDebug() << "[TestUtils]" << "Copy file from" << srcName << "to" << destName; | ||||||
|  |     } | ||||||
|  |     files.clear(); | ||||||
|  |     files = sourceDir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot); | ||||||
|  |     for (int i = 0; i < files.count(); i++) { | ||||||
|  |         QString srcName = sourceFolder + "/" + files[i]; | ||||||
|  |         QString destName = destFolder + "/" + files[i]; | ||||||
|  |         this->copyFolder(srcName, destName); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | QObject *TestsUtils::getTestPassphraseProvider() | ||||||
| { | { | ||||||
|     return this->m_passphrase_povider.get(); |     return this->m_passphrase_povider.get(); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -19,7 +19,10 @@ public: | |||||||
|     ~TestsUtils() override = default; |     ~TestsUtils() override = default; | ||||||
|  |  | ||||||
|     Q_INVOKABLE QString getTempPath(); |     Q_INVOKABLE QString getTempPath(); | ||||||
|     Q_INVOKABLE QObject* getTestPassphraseProvider(); |     Q_INVOKABLE bool fileExists(QUrl path); | ||||||
|  |     Q_INVOKABLE void copyFolder(QUrl sourceFolder, QUrl destFolder); | ||||||
|  |     Q_INVOKABLE QObject *getTestPassphraseProvider(); | ||||||
|  |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -1,13 +1,19 @@ | |||||||
|  | import Pass 1.0 | ||||||
| import QtQuick 2.9 | import QtQuick 2.9 | ||||||
| import QtTest 1.2 | import QtTest 1.2 | ||||||
| import TestsUtils 1.0 | import TestsUtils 1.0 | ||||||
| import Pass 1.0 |  | ||||||
|  |  | ||||||
| TestCase { | TestCase { | ||||||
|  |     property string password_store | ||||||
|  |     property string gpg_home | ||||||
|  |  | ||||||
|     function init() { |     function init() { | ||||||
|         Pass.initialize(null); |         Pass.initialize(null); | ||||||
|         Pass.gpg_home = TestsUtils.getTempPath(); |         gpg_home = TestsUtils.getTempPath(); | ||||||
|         Pass.password_store = TestsUtils.getTempPath(); |         Pass.gpg_home = gpg_home; | ||||||
|  |         password_store = TestsUtils.getTempPath(); | ||||||
|  |         Pass.password_store = password_store; | ||||||
|         Pass.passphrase_provider = TestsUtils.getTestPassphraseProvider(); |         Pass.passphrase_provider = TestsUtils.getTestPassphraseProvider(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										52
									
								
								tests/units/pass/tst_get_keys.qml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								tests/units/pass/tst_get_keys.qml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | |||||||
|  | import Pass 1.0 | ||||||
|  | import QtQuick 2.9 | ||||||
|  | import QtTest 1.2 | ||||||
|  | import TestsUtils 1.0 | ||||||
|  |  | ||||||
|  | PassTestCase { | ||||||
|  |     function init_data() { | ||||||
|  |         //TODO some additionanl error test | ||||||
|  |  | ||||||
|  |         return [{ | ||||||
|  |             "spy": getAllGPGKeysSucceed, | ||||||
|  |             "signal": Pass.getAllGPGKeysSucceed, | ||||||
|  |             "err_msg": null, | ||||||
|  |             "add_home_gpg_data": false, | ||||||
|  |             "nb_keys": 0 | ||||||
|  |         }, { | ||||||
|  |             "spy": getAllGPGKeysSucceed, | ||||||
|  |             "signal": Pass.getAllGPGKeysSucceed, | ||||||
|  |             "err_msg": null, | ||||||
|  |             "add_home_gpg_data": true, | ||||||
|  |             "nb_keys": 2 | ||||||
|  |         }]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function test_get_keys(data) { | ||||||
|  |         if (data.add_home_gpg_data === true) | ||||||
|  |             TestsUtils.copyFolder(Qt.resolvedUrl("../../assets/gpghome"), Qt.resolvedUrl(gpg_home)); | ||||||
|  |  | ||||||
|  |         var keys; | ||||||
|  |         data.signal.connect(function(keys_info) { | ||||||
|  |             keys = keys_info; | ||||||
|  |         }); | ||||||
|  |         Pass.getAllGPGKeys(); | ||||||
|  |         data.spy.wait(); | ||||||
|  |         verify(keys.length === data.nb_keys, "Nb keys %1 but was excepted %2".arg(keys.length).arg(data.nb_keys)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     SignalSpy { | ||||||
|  |         id: getAllGPGKeysSucceed | ||||||
|  |  | ||||||
|  |         target: Pass | ||||||
|  |         signalName: "getAllGPGKeysSucceed" | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     SignalSpy { | ||||||
|  |         id: getAllGPGKeysFailed | ||||||
|  |  | ||||||
|  |         target: Pass | ||||||
|  |         signalName: "getAllGPGKeysFailed" | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -1,47 +1,56 @@ | |||||||
|  | import Pass 1.0 | ||||||
| import QtQuick 2.9 | import QtQuick 2.9 | ||||||
| import QtTest 1.2 | import QtTest 1.2 | ||||||
| import TestsUtils 1.0 | import TestsUtils 1.0 | ||||||
| import Pass 1.0 |  | ||||||
|  |  | ||||||
| PassTestCase { | PassTestCase { | ||||||
|     function init_data() { |     function init_data() { | ||||||
|           return [ |         return [{ | ||||||
|                 { file: Qt.resolvedUrl("../../assets/gpg/test_key.gpg"), spy: importGPGKeySucceed, signal: Pass.importGPGKeySucceed, err_msg : null  } |             "file": Qt.resolvedUrl("../../assets/gpg/test_key.gpg"), | ||||||
|               , { file: Qt.resolvedUrl("../../assets/gpg/test_key_do_not_exist.gpg"), spy: importGPGKeyFailed, signal: Pass.importGPGKeyFailed, err_msg : "Error reading file" } |             "spy": importGPGKeySucceed, | ||||||
|               , { file: Qt.resolvedUrl("../../assets/gpg/test_key_invalid.gpg"), spy: importGPGKeyFailed, signal: Pass.importGPGKeyFailed, err_msg : "Bad format" } |             "signal": Pass.importGPGKeySucceed, | ||||||
|           ]; |             "err_msg": null | ||||||
|  |         }, { | ||||||
|  |             "file": Qt.resolvedUrl("../../assets/gpg/test_key_do_not_exist.gpg"), | ||||||
|  |             "spy": importGPGKeyFailed, | ||||||
|  |             "signal": Pass.importGPGKeyFailed, | ||||||
|  |             "err_msg": "Error reading file" | ||||||
|  |         }, { | ||||||
|  |             "file": Qt.resolvedUrl("../../assets/gpg/test_key_invalid.gpg"), | ||||||
|  |             "spy": importGPGKeyFailed, | ||||||
|  |             "signal": Pass.importGPGKeyFailed, | ||||||
|  |             "err_msg": "Bad state" | ||||||
|  |         }]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function test_import_key(data) { | ||||||
|  |         var err_msg; | ||||||
|  |         data.signal.connect(function(message) { | ||||||
|  |             err_msg = message; | ||||||
|  |         }); | ||||||
|  |         Pass.importGPGKey(data.file); | ||||||
|  |         data.spy.wait(); | ||||||
|  |         if (data.err_msg) { | ||||||
|  |             verify(err_msg === data.err_msg, "Should return arg msg %1 but return %2".arg(data.err_msg).arg(err_msg)); | ||||||
|  |         } else { | ||||||
|  |             console.info(Qt.resolvedUrl("%1/pubkeyring.pgp".arg(gpg_home))); | ||||||
|  |             verify(TestsUtils.fileExists(Qt.resolvedUrl("%1/pubring.pgp".arg(gpg_home))), "%1/pubring.pgp should be created".arg(gpg_home)); | ||||||
|  |             verify(TestsUtils.fileExists(Qt.resolvedUrl("%1/secring.pgp".arg(gpg_home))), "%1/secring.pgp should be created".arg(gpg_home)); | ||||||
|         } |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     SignalSpy { |     SignalSpy { | ||||||
|         id: importGPGKeySucceed |         id: importGPGKeySucceed | ||||||
|  |  | ||||||
|         target: Pass |         target: Pass | ||||||
|         signalName: "importGPGKeySucceed" |         signalName: "importGPGKeySucceed" | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     SignalSpy { |     SignalSpy { | ||||||
|         id: importGPGKeyFailed |         id: importGPGKeyFailed | ||||||
|  |  | ||||||
|         target: Pass |         target: Pass | ||||||
|         signalName: "importGPGKeyFailed" |         signalName: "importGPGKeyFailed" | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     SignalSpy { |  | ||||||
|         id: importGPGKeyCancelled |  | ||||||
|         target: Pass |  | ||||||
|         signalName: "importGPGKeyCancelled" |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     function test_import_key(data) { |  | ||||||
|         var err_msg; |  | ||||||
|  |  | ||||||
|         data.signal.connect(function(message) { |  | ||||||
|             err_msg = message; |  | ||||||
|         }); |  | ||||||
|  |  | ||||||
|         Pass.importGPGKey(data.file); |  | ||||||
|  |  | ||||||
|         data.spy.wait(); |  | ||||||
|         if(data.err_msg) { |  | ||||||
|             verify(err_msg === data.err_msg, "Should return arg msg %1 but return %2".arg(data.err_msg).arg(err_msg)); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -3,9 +3,9 @@ import QtQuick 2.9 | |||||||
| import QtTest 1.2 | import QtTest 1.2 | ||||||
|  |  | ||||||
| TestCase { | TestCase { | ||||||
|     function test_import_key(){ |     function test_import_key() { | ||||||
|         var homedir = TestUtils.getTempPath(); |         var homedir = TestUtils.getTempPath(); | ||||||
|         Pass |         Pass; | ||||||
|         verify(false); |         verify(false); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user