diff --git a/td/telegram/ConfigManager.cpp b/td/telegram/ConfigManager.cpp index 7bd25139b..8ad4ca30a 100644 --- a/td/telegram/ConfigManager.cpp +++ b/td/telegram/ConfigManager.cpp @@ -32,7 +32,6 @@ #include "td/mtproto/RSA.h" #include "td/mtproto/TransportType.h" -#include "td/net/HttpQuery.h" #if !TD_EMSCRIPTEN //FIXME #include "td/net/SslStream.h" #include "td/net/Wget.h" @@ -890,11 +889,6 @@ void ConfigManager::start_up() { expire_time_ = expire_time; set_timeout_in(expire_time_.in()); } - - autologin_update_time_ = Time::now() - 365 * 86400; - autologin_domains_ = full_split(G()->td_db()->get_binlog_pmc()->get("autologin_domains"), '\xFF'); - - url_auth_domains_ = full_split(G()->td_db()->get_binlog_pmc()->get("url_auth_domains"), '\xFF'); } ActorShared<> ConfigManager::create_reference() { @@ -971,65 +965,6 @@ void ConfigManager::get_app_config(Promise } } -void ConfigManager::get_external_link_info(string &&link, Promise> &&promise) { - auto default_result = td_api::make_object(link, false); - if (G()->close_flag()) { - return promise.set_value(std::move(default_result)); - } - - auto r_url = parse_url(link); - if (r_url.is_error()) { - return promise.set_value(std::move(default_result)); - } - - if (!td::contains(autologin_domains_, r_url.ok().host_)) { - if (td::contains(url_auth_domains_, r_url.ok().host_)) { - send_closure(G()->link_manager(), &LinkManager::get_link_login_url_info, link, std::move(promise)); - return; - } - return promise.set_value(std::move(default_result)); - } - - if (autologin_update_time_ < Time::now() - 10000) { - auto query_promise = PromiseCreator::lambda([link = std::move(link), promise = std::move(promise)]( - Result> &&result) mutable { - if (result.is_error()) { - return promise.set_value(td_api::make_object(link, false)); - } - send_closure(G()->config_manager(), &ConfigManager::get_external_link_info, std::move(link), std::move(promise)); - }); - return get_app_config(std::move(query_promise)); - } - - if (autologin_token_.empty()) { - return promise.set_value(std::move(default_result)); - } - - auto url = r_url.move_as_ok(); - url.protocol_ = HttpUrl::Protocol::Https; - Slice path = url.query_; - path.truncate(url.query_.find_first_of("?#")); - Slice parameters_hash = Slice(url.query_).substr(path.size()); - Slice parameters = parameters_hash; - parameters.truncate(parameters.find('#')); - Slice hash = parameters_hash.substr(parameters.size()); - - string added_parameter; - if (parameters.empty()) { - added_parameter = '?'; - } else if (parameters.size() == 1) { - CHECK(parameters == "?"); - } else { - added_parameter = '&'; - } - added_parameter += "autologin_token="; - added_parameter += autologin_token_; - - url.query_ = PSTRING() << path << parameters << added_parameter << hash; - - promise.set_value(td_api::make_object(url.get_url(), false)); -} - void ConfigManager::get_content_settings(Promise &&promise) { if (G()->close_flag()) { return promise.set_error(Status::Error(500, "Request aborted")); @@ -1528,13 +1463,9 @@ void ConfigManager::process_app_config(tl_object_ptr &c const bool archive_and_mute = G()->shared_config().get_option_boolean("archive_and_mute_new_chats_from_unknown_users"); - autologin_token_.clear(); - auto old_autologin_domains = std::move(autologin_domains_); - autologin_domains_.clear(); - autologin_update_time_ = Time::now(); - - auto old_url_auth_domains = std::move(url_auth_domains_); - url_auth_domains_.clear(); + string autologin_token; + vector autologin_domains; + vector url_auth_domains; vector> new_values; string ignored_restriction_reasons; @@ -1704,7 +1635,7 @@ void ConfigManager::process_app_config(tl_object_ptr &c } if (key == "autologin_token") { if (value->get_id() == telegram_api::jsonString::ID) { - autologin_token_ = url_encode(static_cast(value)->value_); + autologin_token = url_encode(static_cast(value)->value_); } else { LOG(ERROR) << "Receive unexpected autologin_token " << to_string(*value); } @@ -1716,7 +1647,7 @@ void ConfigManager::process_app_config(tl_object_ptr &c for (auto &domain : domains) { CHECK(domain != nullptr); if (domain->get_id() == telegram_api::jsonString::ID) { - autologin_domains_.push_back(std::move(static_cast(domain.get())->value_)); + autologin_domains.push_back(std::move(static_cast(domain.get())->value_)); } else { LOG(ERROR) << "Receive unexpected autologin domain " << to_string(domain); } @@ -1732,7 +1663,7 @@ void ConfigManager::process_app_config(tl_object_ptr &c for (auto &domain : domains) { CHECK(domain != nullptr); if (domain->get_id() == telegram_api::jsonString::ID) { - url_auth_domains_.push_back(std::move(static_cast(domain.get())->value_)); + url_auth_domains.push_back(std::move(static_cast(domain.get())->value_)); } else { LOG(ERROR) << "Receive unexpected url auth domain " << to_string(domain); } @@ -1750,12 +1681,8 @@ void ConfigManager::process_app_config(tl_object_ptr &c } config = make_tl_object(std::move(new_values)); - if (autologin_domains_ != old_autologin_domains) { - G()->td_db()->get_binlog_pmc()->set("autologin_domains", implode(autologin_domains_, '\xFF')); - } - if (url_auth_domains_ != old_url_auth_domains) { - G()->td_db()->get_binlog_pmc()->set("url_auth_domains", implode(url_auth_domains_, '\xFF')); - } + send_closure(G()->link_manager(), &LinkManager::update_autologin_domains, std::move(autologin_token), + std::move(autologin_domains), std::move(url_auth_domains)); ConfigShared &shared_config = G()->shared_config(); diff --git a/td/telegram/ConfigManager.h b/td/telegram/ConfigManager.h index 978268113..d93b9099d 100644 --- a/td/telegram/ConfigManager.h +++ b/td/telegram/ConfigManager.h @@ -93,8 +93,6 @@ class ConfigManager : public NetQueryCallback { void get_app_config(Promise> &&promise); - void get_external_link_info(string &&link, Promise> &&promise); - void get_content_settings(Promise &&promise); void set_content_settings(bool ignore_sensitive_content_restrictions, Promise &&promise); @@ -116,11 +114,6 @@ class ConfigManager : public NetQueryCallback { int ref_cnt_{1}; Timestamp expire_time_; - string autologin_token_; - vector autologin_domains_; - double autologin_update_time_ = 0.0; - vector url_auth_domains_; - FloodControlStrict lazy_request_flood_control_; vector>> get_app_config_queries_; diff --git a/td/telegram/LinkManager.cpp b/td/telegram/LinkManager.cpp index 2bce4ec82..60ace66b6 100644 --- a/td/telegram/LinkManager.cpp +++ b/td/telegram/LinkManager.cpp @@ -8,6 +8,7 @@ #include "td/telegram/AccessRights.h" #include "td/telegram/ChannelId.h" +#include "td/telegram/ConfigManager.h" #include "td/telegram/ConfigShared.h" #include "td/telegram/ContactsManager.h" #include "td/telegram/Global.h" @@ -15,6 +16,7 @@ #include "td/telegram/MessagesManager.h" #include "td/telegram/ServerMessageId.h" #include "td/telegram/Td.h" +#include "td/telegram/TdDb.h" #include "td/telegram/telegram_api.h" #include "td/telegram/UserId.h" @@ -28,6 +30,7 @@ #include "td/utils/misc.h" #include "td/utils/SliceBuilder.h" #include "td/utils/StringBuilder.h" +#include "td/utils/Time.h" namespace td { @@ -457,6 +460,13 @@ LinkManager::LinkManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::m LinkManager::~LinkManager() = default; +void LinkManager::start_up() { + autologin_update_time_ = Time::now() - 365 * 86400; + autologin_domains_ = full_split(G()->td_db()->get_binlog_pmc()->get("autologin_domains"), '\xFF'); + + url_auth_domains_ = full_split(G()->td_db()->get_binlog_pmc()->get("url_auth_domains"), '\xFF'); +} + void LinkManager::tear_down() { parent_.reset(); } @@ -979,6 +989,79 @@ unique_ptr LinkManager::get_internal_link_passport( callback_url.str()); } +void LinkManager::update_autologin_domains(string autologin_token, vector autologin_domains, + vector url_auth_domains) { + autologin_update_time_ = Time::now(); + autologin_token = std::move(autologin_token); + if (autologin_domains_ != autologin_domains) { + autologin_domains_ = std::move(autologin_domains); + G()->td_db()->get_binlog_pmc()->set("autologin_domains", implode(autologin_domains_, '\xFF')); + } + if (url_auth_domains_ != url_auth_domains) { + url_auth_domains_ = std::move(url_auth_domains); + G()->td_db()->get_binlog_pmc()->set("url_auth_domains", implode(url_auth_domains_, '\xFF')); + } +} + +void LinkManager::get_external_link_info(string &&link, Promise> &&promise) { + auto default_result = td_api::make_object(link, false); + if (G()->close_flag()) { + return promise.set_value(std::move(default_result)); + } + + auto r_url = parse_url(link); + if (r_url.is_error()) { + return promise.set_value(std::move(default_result)); + } + + if (!td::contains(autologin_domains_, r_url.ok().host_)) { + if (td::contains(url_auth_domains_, r_url.ok().host_)) { + td_->create_handler(std::move(promise))->send(link, DialogId(), MessageId(), 0); + return; + } + return promise.set_value(std::move(default_result)); + } + + if (autologin_update_time_ < Time::now() - 10000) { + auto query_promise = PromiseCreator::lambda([link = std::move(link), promise = std::move(promise)]( + Result> &&result) mutable { + if (result.is_error()) { + return promise.set_value(td_api::make_object(link, false)); + } + send_closure(G()->link_manager(), &LinkManager::get_external_link_info, std::move(link), std::move(promise)); + }); + return send_closure(G()->config_manager(), &ConfigManager::get_app_config, std::move(query_promise)); + } + + if (autologin_token_.empty()) { + return promise.set_value(std::move(default_result)); + } + + auto url = r_url.move_as_ok(); + url.protocol_ = HttpUrl::Protocol::Https; + Slice path = url.query_; + path.truncate(url.query_.find_first_of("?#")); + Slice parameters_hash = Slice(url.query_).substr(path.size()); + Slice parameters = parameters_hash; + parameters.truncate(parameters.find('#')); + Slice hash = parameters_hash.substr(parameters.size()); + + string added_parameter; + if (parameters.empty()) { + added_parameter = '?'; + } else if (parameters.size() == 1) { + CHECK(parameters == "?"); + } else { + added_parameter = '&'; + } + added_parameter += "autologin_token="; + added_parameter += autologin_token_; + + url.query_ = PSTRING() << path << parameters << added_parameter << hash; + + promise.set_value(td_api::make_object(url.get_url(), false)); +} + void LinkManager::get_login_url_info(DialogId dialog_id, MessageId message_id, int32 button_id, Promise> &&promise) { TRY_RESULT_PROMISE(promise, url, td_->messages_manager_->get_login_button_url(dialog_id, message_id, button_id)); @@ -992,15 +1075,6 @@ void LinkManager::get_login_url(DialogId dialog_id, MessageId message_id, int32 ->send(std::move(url), dialog_id, message_id, button_id, allow_write_access); } -void LinkManager::get_link_login_url_info(const string &url, - Promise> &&promise) { - if (G()->close_flag()) { - return promise.set_value(td_api::make_object(url, false)); - } - - td_->create_handler(std::move(promise))->send(url, DialogId(), MessageId(), 0); -} - void LinkManager::get_link_login_url(const string &url, bool allow_write_access, Promise> &&promise) { td_->create_handler(std::move(promise)) diff --git a/td/telegram/LinkManager.h b/td/telegram/LinkManager.h index fb06c9064..abb2170b1 100644 --- a/td/telegram/LinkManager.h +++ b/td/telegram/LinkManager.h @@ -52,14 +52,17 @@ class LinkManager : public Actor { // checks whether the link is a supported tg or t.me link and parses it static unique_ptr parse_internal_link(Slice link); + void update_autologin_domains(string autologin_token, vector autologin_domains, + vector url_auth_domains); + + void get_external_link_info(string &&link, Promise> &&promise); + void get_login_url_info(DialogId dialog_id, MessageId message_id, int32 button_id, Promise> &&promise); void get_login_url(DialogId dialog_id, MessageId message_id, int32 button_id, bool allow_write_access, Promise> &&promise); - void get_link_login_url_info(const string &url, Promise> &&promise); - void get_link_login_url(const string &url, bool allow_write_access, Promise> &&promise); @@ -68,7 +71,9 @@ class LinkManager : public Actor { static Result get_message_link_info(Slice url); private: - void tear_down() override; + void start_up() final; + + void tear_down() final; class InternalLinkActiveSessions; class InternalLinkAuthenticationCode; @@ -112,6 +117,11 @@ class LinkManager : public Actor { Td *td_; ActorShared<> parent_; + + string autologin_token_; + vector autologin_domains_; + double autologin_update_time_ = 0.0; + vector url_auth_domains_; }; } // namespace td diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index e2cf9ecf9..96757501c 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -5497,8 +5497,7 @@ void Td::on_request(uint64 id, td_api::getExternalLinkInfo &request) { CHECK_IS_USER(); CLEAN_INPUT_STRING(request.link_); CREATE_REQUEST_PROMISE(); - send_closure_later(G()->config_manager(), &ConfigManager::get_external_link_info, std::move(request.link_), - std::move(promise)); + link_manager_->get_external_link_info(std::move(request.link_), std::move(promise)); } void Td::on_request(uint64 id, td_api::getExternalLink &request) {