From a5c749701af2fe58fafff36f679a593bc3380421 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sun, 3 Apr 2022 13:24:38 +0200 Subject: Make saucenao work when using pantalaimon (doesn't work for encrypted rooms) --- TODO | 3 ++- plugins/Matrix.hpp | 2 ++ src/QuickMedia.cpp | 22 ++++++++++++++++++++++ src/plugins/Matrix.cpp | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 62 insertions(+), 1 deletion(-) diff --git a/TODO b/TODO index c78db7a..73eb504 100644 --- a/TODO +++ b/TODO @@ -222,4 +222,5 @@ Zero clear password memory after use. Periodically cleanup old cache files (especially manga images, thumbnails and media). Maybe have a file that says when we last checked for old files, and if its X days old then check and remove old files again and update the file. Render watch progress in youtube. -Set _NET_WM_USER_TIME (see sfml). \ No newline at end of file +Set _NET_WM_USER_TIME (see sfml). +Make saucenao work with encrypted images in matrix, or show an error as this is a "security" risk. \ No newline at end of file diff --git a/plugins/Matrix.hpp b/plugins/Matrix.hpp index 9b0fc58..0c12831 100644 --- a/plugins/Matrix.hpp +++ b/plugins/Matrix.hpp @@ -580,6 +580,7 @@ namespace QuickMedia { std::shared_ptr get_me(RoomData *room); const std::string& get_homeserver_domain() const; + std::string get_remote_homeserver_url() const; // Returns nullptr if message cant be found. Note: cached std::shared_ptr get_message_by_id(RoomData *room, const std::string &event_id); @@ -647,6 +648,7 @@ namespace QuickMedia { std::string access_token; std::string homeserver; std::string homeserver_domain; + std::string well_known_base_url; std::optional upload_limit; std::string next_batch; std::string next_notifications_token; diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index da76335..101fa59 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -5246,6 +5246,26 @@ namespace QuickMedia { return message; } + static std::string pantalaimon_image_proxy_url_to_remote_image_url(Matrix *matrix, const std::string &image_url) { + std::string remote_homeserver_url = matrix->get_remote_homeserver_url(); + if(!remote_homeserver_url.empty() && remote_homeserver_url.back() == '/') + remote_homeserver_url.pop_back(); + + std::string result_url = image_url; + + if(string_starts_with(result_url, "http://")) + result_url.erase(result_url.begin(), result_url.begin() + 7); + else if(string_starts_with(result_url, "https://")) + result_url.erase(result_url.begin(), result_url.begin() + 8); + + size_t path_index = result_url.find('/'); + if(path_index == std::string::npos) + return remote_homeserver_url; + + result_url.replace(0, path_index, remote_homeserver_url); + return result_url; + } + bool Program::chat_page(MatrixChatPage *matrix_chat_page, RoomData *current_room) { assert(current_room); assert(strcmp(plugin_name, "matrix") == 0); @@ -6627,6 +6647,8 @@ namespace QuickMedia { if(selected_item_message->type == MessageType::VIDEO) image_url = selected_item->thumbnail_url; + image_url = pantalaimon_image_proxy_url_to_remote_image_url(matrix, image_url); + std::vector saucenao_tabs; saucenao_tabs.push_back(Tab{create_body(), std::make_unique(this, image_url, false), nullptr}); page_loop(saucenao_tabs); diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp index 144bbd8..5306349 100644 --- a/src/plugins/Matrix.cpp +++ b/src/plugins/Matrix.cpp @@ -3863,6 +3863,16 @@ namespace QuickMedia { if(home_server_json.IsString()) this->homeserver_domain = home_server_json.GetString(); + const rapidjson::Value &well_known_json = GetMember(json_root, "well_known"); + if(well_known_json.IsObject()) { + const rapidjson::Value &homeserver_json = GetMember(well_known_json, "m.homeserver"); + if(homeserver_json.IsObject()) { + const rapidjson::Value &base_url_json = GetMember(homeserver_json, "base_url"); + if(base_url_json.IsString()) + well_known_base_url = base_url_json.GetString(); + } + } + // Use the user-provided homeserver instead of the one the server tells us about, otherwise this wont work with a proxy // such as pantalaimon json_root.AddMember("homeserver", rapidjson::StringRef(homeserver.c_str()), request_data.GetAllocator()); @@ -3906,6 +3916,7 @@ namespace QuickMedia { access_token.clear(); homeserver.clear(); homeserver_domain.clear(); + well_known_base_url.clear(); upload_limit.reset(); return PluginResult::OK; @@ -4103,6 +4114,16 @@ namespace QuickMedia { if(home_server_json.IsString()) this->homeserver_domain = home_server_json.GetString(); + const rapidjson::Value &well_known_json = GetMember(json_root, "well_known"); + if(well_known_json.IsObject()) { + const rapidjson::Value &homeserver_json = GetMember(well_known_json, "m.homeserver"); + if(homeserver_json.IsObject()) { + const rapidjson::Value &base_url_json = GetMember(homeserver_json, "base_url"); + if(base_url_json.IsString()) + well_known_base_url = base_url_json.GetString(); + } + } + this->my_user_id = user_id_json.GetString(); this->access_token = access_token_json.GetString(); this->homeserver = homeserver_json.GetString(); @@ -4527,6 +4548,21 @@ namespace QuickMedia { return homeserver_domain; } + std::string Matrix::get_remote_homeserver_url() const { + if(!well_known_base_url.empty()) + return well_known_base_url; + + if(!homeserver_domain.empty()) { + if(string_starts_with(homeserver_domain, "http://") || string_starts_with(homeserver_domain, "https://")) + return homeserver_domain; + return "https://" + homeserver_domain; // TODO: What if domain does not use https? + } + + if(string_starts_with(homeserver, "http://") || string_starts_with(homeserver, "https://")) + return homeserver; + return "https://" + homeserver; // TODO: What if domain does not use https? + } + RoomData* Matrix::get_room_by_id(const std::string &id) { std::lock_guard lock(room_data_mutex); auto room_it = room_data_by_id.find(id); -- cgit v1.2.3