diff --git a/include/providers/encrypt/encrypt_provider.hpp b/include/providers/encrypt/encrypt_provider.hpp index 0ab81d88..63c73060 100644 --- a/include/providers/encrypt/encrypt_provider.hpp +++ b/include/providers/encrypt/encrypt_provider.hpp @@ -65,7 +65,7 @@ private: static void create_item_meta(api_meta_map &meta, bool directory, const api_file &file); - [[nodiscard]] auto + auto process_directory_entry(const std::filesystem::directory_entry &dir_entry, const encrypt_config &cfg, std::string &api_path) const -> bool; diff --git a/scripts/make_common.sh b/scripts/make_common.sh index f5936092..4120ac33 100644 --- a/scripts/make_common.sh +++ b/scripts/make_common.sh @@ -51,7 +51,7 @@ pushd .. ln -sf ${BUILD_FOLDER}/compile_commands.json . ln -sf ${BUILD_FOLDER}/repertory${EXE_EXT} . ln -sf ${BUILD_FOLDER}/unittests${EXE_EXT} . -if [ "${IS_MINGW}" == "1" ]; then +if [ "${IS_MINGW}" == "1" ] || [ "${IS_WIN32}" == "1" ]; then ln -sf ${BUILD_FOLDER}/winfsp-x64.dll . fi popd @@ -67,7 +67,7 @@ pushd ../${BUILD_ROOT} ln -sf ${BUILD_FOLDER}/compile_commands.json . ln -sf ${BUILD_FOLDER}/repertory${EXE_EXT} . ln -sf ${BUILD_FOLDER}/unittests${EXE_EXT} . -if [ "${IS_MINGW}" == "1" ]; then +if [ "${IS_MINGW}" == "1" ] || [ "${IS_WIN32}" == "1" ]; then ln -sf ${BUILD_FOLDER}/winfsp-x64.dll . fi popd diff --git a/src/providers/encrypt/encrypt_provider.cpp b/src/providers/encrypt/encrypt_provider.cpp index c271c531..ce09ce1a 100644 --- a/src/providers/encrypt/encrypt_provider.cpp +++ b/src/providers/encrypt/encrypt_provider.cpp @@ -26,9 +26,9 @@ #include "database/db_select.hpp" #include "events/event_system.hpp" #include "events/events.hpp" -#include "platform/platform.hpp" #include "types/repertory.hpp" #include "utils/encrypting_reader.hpp" +#include "utils/encryption.hpp" #include "utils/path_utils.hpp" #include "utils/polling.hpp" @@ -299,17 +299,21 @@ auto encrypt_provider::get_directory_items(const std::string &api_path, const auto cfg = config_.get_encrypt_config(); for (const auto &child_dir_entry : std::filesystem::directory_iterator(dir_entry.path())) { - if (process_directory_entry(child_dir_entry, cfg, - current_api_path)) { - current_api_path = - utils::path::get_parent_api_path(current_api_path); - break; - } + process_directory_entry(child_dir_entry, cfg, current_api_path); } - if (current_api_path.empty()) { + result = db::db_select{*db_, directory_table} + .column("api_path") + .where("source_path") + .equals(dir_entry.path().string()) + .go(); + row.reset(); + if (not(result.get_row(row) && row.has_value())) { continue; } + + current_api_path = + row->get_column("api_path").get_value(); } } else { std::string api_path_data{}; @@ -406,8 +410,78 @@ auto encrypt_provider::get_file(const std::string &api_path, auto encrypt_provider::process_directory_entry( const std::filesystem::directory_entry &dir_entry, const encrypt_config &cfg, std::string &api_path) const -> bool { - if (dir_entry.is_regular_file() && not dir_entry.is_symlink() && - not dir_entry.is_directory()) { + const auto add_directory = [this, &cfg](auto dir_path) -> std::string { + auto encrypted_parts = utils::string::split( + utils::path::create_api_path(dir_path.string()), '/', false); + + for (std::size_t part_idx = 0U; part_idx < encrypted_parts.size(); + part_idx++) { + data_buffer encrypted_data; + utils::encryption::encrypt_data( + cfg.encryption_token, encrypted_parts.at(part_idx).c_str(), + strnlen(encrypted_parts.at(part_idx).c_str(), + encrypted_parts.at(part_idx).size()), + encrypted_data); + encrypted_parts[part_idx] = utils::to_hex_string(encrypted_data); + } + + std::size_t current_idx{}; + std::string current_encrypted_path{}; + std::string current_source_path{cfg.path}; + for (const auto &part : dir_path) { + if (part.string() == "/") { + continue; + } + + current_source_path = + utils::path::combine(current_source_path, {part.string()}); + + std::string parent_api_path{}; + auto result = db::db_select{*db_, directory_table} + .column("api_path") + .where("source_path") + .equals(current_source_path) + .go(); + std::optional row; + if (result.get_row(row) && row.has_value()) { + parent_api_path = row->get_column("api_path").get_value(); + } + + if (parent_api_path.empty()) { + parent_api_path = utils::path::create_api_path( + current_encrypted_path + '/' + encrypted_parts.at(current_idx)); + + auto ins_res = db::db_insert{*db_, directory_table} + .column_value("source_path", current_source_path) + .column_value("api_path", parent_api_path) + .go(); + // TODO handle error + ins_res = db::db_insert{*db_, source_table} + .column_value("api_path", parent_api_path) + .column_value("source_path", current_source_path) + .go(); + // TODO handle error + event_system::instance().raise( + parent_api_path, utils::path::get_parent_api_path(parent_api_path), + true); + } else { + encrypted_parts[current_idx] = + utils::string::split(parent_api_path, '/', false)[current_idx]; + } + + current_encrypted_path = utils::path::create_api_path( + current_encrypted_path + '/' + encrypted_parts[current_idx++]); + } + + return current_encrypted_path; + }; + + if (dir_entry.is_directory()) { + api_path = add_directory(dir_entry.path().lexically_relative(cfg.path)); + return false; + } + + if (dir_entry.is_regular_file() && not dir_entry.is_symlink()) { const auto relative_path = dir_entry.path().lexically_relative(cfg.path); std::string api_path_data{}; @@ -433,69 +507,16 @@ auto encrypt_provider::process_directory_entry( } if (api_path_data.empty() || api_parent.empty()) { - stop_type stop_requested = false; - utils::encryption::encrypting_reader reader( - relative_path.filename().string(), dir_entry.path().string(), - stop_requested, cfg.encryption_token, - relative_path.parent_path().string()); if (api_parent.empty()) { - auto encrypted_parts = - utils::string::split(reader.get_encrypted_file_path(), '/', false); - - std::size_t idx{1U}; - - std::string current_source_path{cfg.path}; - std::string current_encrypted_path{}; - for (const auto &part : relative_path.parent_path()) { - if (part.string() == "/") { - continue; - } - - current_source_path = - utils::path::combine(current_source_path, {part.string()}); - - std::string parent_api_path{}; - result = db::db_select{*db_, directory_table} - .column("api_path") - .where("source_path") - .equals(current_source_path) - .go(); - row.reset(); - if (result.get_row(row) && row.has_value()) { - parent_api_path = - row->get_column("api_path").get_value(); - } - - if (parent_api_path.empty()) { - parent_api_path = utils::path::create_api_path( - current_encrypted_path + '/' + encrypted_parts[idx]); - - auto ins_res = db::db_insert{*db_, directory_table} - .column_value("source_path", current_source_path) - .column_value("api_path", parent_api_path) - .go(); - // TODO handle error - ins_res = db::db_insert{*db_, source_table} - .column_value("api_path", parent_api_path) - .column_value("source_path", current_source_path) - .go(); - // TODO handle error - event_system::instance().raise( - parent_api_path, - utils::path::get_parent_api_path(parent_api_path), true); - } else { - encrypted_parts[idx] = - utils::string::split(parent_api_path, '/', false)[idx]; - } - - current_encrypted_path = utils::path::create_api_path( - current_encrypted_path + '/' + encrypted_parts[idx++]); - } - - api_parent = current_encrypted_path; + api_parent = add_directory(relative_path.parent_path()); } if (api_path_data.empty()) { + stop_type stop_requested = false; + utils::encryption::encrypting_reader reader( + relative_path.filename().string(), dir_entry.path().string(), + stop_requested, cfg.encryption_token, + relative_path.parent_path().string()); api_path = utils::path::create_api_path( api_parent + "/" + reader.get_encrypted_file_name());