mirror of
https://github.com/tdlight-team/tdlight-telegram-bot-api.git
synced 2024-11-27 14:16:49 +01:00
Allow to specify a secret_token in setWebhook to ensure that webhook was set by the domain owner.
This commit is contained in:
parent
fd7489f6da
commit
06d40edb0a
@ -8382,13 +8382,14 @@ td::Status Client::process_set_webhook_query(PromisedQueryPtr &query) {
|
|||||||
int32 new_max_connections = new_url.empty() ? 0 : get_webhook_max_connections(query.get());
|
int32 new_max_connections = new_url.empty() ? 0 : get_webhook_max_connections(query.get());
|
||||||
Slice new_ip_address = new_url.empty() ? Slice() : query->arg("ip_address");
|
Slice new_ip_address = new_url.empty() ? Slice() : query->arg("ip_address");
|
||||||
bool new_fix_ip_address = new_url.empty() ? false : get_webhook_fix_ip_address(query.get());
|
bool new_fix_ip_address = new_url.empty() ? false : get_webhook_fix_ip_address(query.get());
|
||||||
|
Slice new_secret_token = new_url.empty() ? Slice() : query->arg("secret_token");
|
||||||
bool drop_pending_updates = to_bool(query->arg("drop_pending_updates"));
|
bool drop_pending_updates = to_bool(query->arg("drop_pending_updates"));
|
||||||
if (webhook_set_query_) {
|
if (webhook_set_query_) {
|
||||||
// already updating webhook. Cancel previous request
|
// already updating webhook. Cancel previous request
|
||||||
fail_query_conflict("Conflict: terminated by other setWebhook", std::move(webhook_set_query_));
|
fail_query_conflict("Conflict: terminated by other setWebhook", std::move(webhook_set_query_));
|
||||||
} else if (webhook_url_ == new_url && !has_webhook_certificate_ && query->file("certificate") == nullptr &&
|
} else if (webhook_url_ == new_url && !has_webhook_certificate_ && query->file("certificate") == nullptr &&
|
||||||
query->arg("certificate").empty() && new_max_connections == webhook_max_connections_ &&
|
query->arg("certificate").empty() && new_max_connections == webhook_max_connections_ &&
|
||||||
new_fix_ip_address == webhook_fix_ip_address_ &&
|
new_fix_ip_address == webhook_fix_ip_address_ && new_secret_token == webhook_secret_token_ &&
|
||||||
(!new_fix_ip_address || new_ip_address == webhook_ip_address_) && !drop_pending_updates) {
|
(!new_fix_ip_address || new_ip_address == webhook_ip_address_) && !drop_pending_updates) {
|
||||||
if (update_allowed_update_types(query.get())) {
|
if (update_allowed_update_types(query.get())) {
|
||||||
save_webhook();
|
save_webhook();
|
||||||
@ -8512,6 +8513,9 @@ void Client::save_webhook() const {
|
|||||||
if (webhook_fix_ip_address_) {
|
if (webhook_fix_ip_address_) {
|
||||||
value += "#fix_ip/";
|
value += "#fix_ip/";
|
||||||
}
|
}
|
||||||
|
if (!webhook_secret_token_.empty()) {
|
||||||
|
value += PSTRING() << "#secret" << webhook_secret_token_ << '/';
|
||||||
|
}
|
||||||
if (allowed_update_types_ != DEFAULT_ALLOWED_UPDATE_TYPES) {
|
if (allowed_update_types_ != DEFAULT_ALLOWED_UPDATE_TYPES) {
|
||||||
value += PSTRING() << "#allow" << allowed_update_types_ << '/';
|
value += PSTRING() << "#allow" << allowed_update_types_ << '/';
|
||||||
}
|
}
|
||||||
@ -8555,6 +8559,7 @@ void Client::webhook_closed(Status status) {
|
|||||||
webhook_max_connections_ = 0;
|
webhook_max_connections_ = 0;
|
||||||
webhook_ip_address_ = td::string();
|
webhook_ip_address_ = td::string();
|
||||||
webhook_fix_ip_address_ = false;
|
webhook_fix_ip_address_ = false;
|
||||||
|
webhook_secret_token_ = td::string();
|
||||||
webhook_set_time_ = td::Time::now();
|
webhook_set_time_ = td::Time::now();
|
||||||
last_webhook_error_date_ = 0;
|
last_webhook_error_date_ = 0;
|
||||||
last_webhook_error_ = Status::OK();
|
last_webhook_error_ = Status::OK();
|
||||||
@ -8604,6 +8609,13 @@ void Client::do_set_webhook(PromisedQueryPtr query, bool was_deleted) {
|
|||||||
if (url.is_error()) {
|
if (url.is_error()) {
|
||||||
return fail_query(400, "Bad Request: invalid webhook URL specified", std::move(query));
|
return fail_query(400, "Bad Request: invalid webhook URL specified", std::move(query));
|
||||||
}
|
}
|
||||||
|
auto secret_token = query->arg("secret_token");
|
||||||
|
if (secret_token.size() > 256) {
|
||||||
|
return fail_query(400, "Bad Request: secret token is too long", std::move(query));
|
||||||
|
}
|
||||||
|
if (!td::is_base64url_characters(secret_token)) {
|
||||||
|
return fail_query(400, "Bad Request: secret token contains unallowed characters", std::move(query));
|
||||||
|
}
|
||||||
auto *cert_file_ptr = query->file("certificate");
|
auto *cert_file_ptr = query->file("certificate");
|
||||||
has_webhook_certificate_ = false;
|
has_webhook_certificate_ = false;
|
||||||
if (cert_file_ptr != nullptr) {
|
if (cert_file_ptr != nullptr) {
|
||||||
@ -8627,6 +8639,7 @@ void Client::do_set_webhook(PromisedQueryPtr query, bool was_deleted) {
|
|||||||
webhook_url_ = new_url.str();
|
webhook_url_ = new_url.str();
|
||||||
webhook_set_time_ = td::Time::now();
|
webhook_set_time_ = td::Time::now();
|
||||||
webhook_max_connections_ = get_webhook_max_connections(query.get());
|
webhook_max_connections_ = get_webhook_max_connections(query.get());
|
||||||
|
webhook_secret_token_ = secret_token.str();
|
||||||
webhook_ip_address_ = query->arg("ip_address").str();
|
webhook_ip_address_ = query->arg("ip_address").str();
|
||||||
webhook_fix_ip_address_ = get_webhook_fix_ip_address(query.get());
|
webhook_fix_ip_address_ = get_webhook_fix_ip_address(query.get());
|
||||||
last_webhook_error_date_ = 0;
|
last_webhook_error_date_ = 0;
|
||||||
@ -8639,7 +8652,7 @@ void Client::do_set_webhook(PromisedQueryPtr query, bool was_deleted) {
|
|||||||
webhook_id_ = td::create_actor<WebhookActor>(
|
webhook_id_ = td::create_actor<WebhookActor>(
|
||||||
webhook_actor_name, actor_shared(this, webhook_generation_), tqueue_id_, url.move_as_ok(),
|
webhook_actor_name, actor_shared(this, webhook_generation_), tqueue_id_, url.move_as_ok(),
|
||||||
has_webhook_certificate_ ? get_webhook_certificate_path() : "", webhook_max_connections_, query->is_internal(),
|
has_webhook_certificate_ ? get_webhook_certificate_path() : "", webhook_max_connections_, query->is_internal(),
|
||||||
webhook_ip_address_, webhook_fix_ip_address_, parameters_);
|
webhook_ip_address_, webhook_fix_ip_address_, webhook_secret_token_, parameters_);
|
||||||
// wait for webhook verified or webhook callback
|
// wait for webhook verified or webhook callback
|
||||||
webhook_query_type_ = WebhookQueryType::Verify;
|
webhook_query_type_ = WebhookQueryType::Verify;
|
||||||
webhook_set_query_ = std::move(query);
|
webhook_set_query_ = std::move(query);
|
||||||
|
@ -1007,6 +1007,7 @@ class Client final : public WebhookActor::Callback {
|
|||||||
int32 webhook_max_connections_ = 0;
|
int32 webhook_max_connections_ = 0;
|
||||||
td::string webhook_ip_address_;
|
td::string webhook_ip_address_;
|
||||||
bool webhook_fix_ip_address_ = false;
|
bool webhook_fix_ip_address_ = false;
|
||||||
|
td::string webhook_secret_token_;
|
||||||
int32 last_webhook_error_date_ = 0;
|
int32 last_webhook_error_date_ = 0;
|
||||||
Status last_webhook_error_;
|
Status last_webhook_error_;
|
||||||
double next_allowed_set_webhook_time_ = 0;
|
double next_allowed_set_webhook_time_ = 0;
|
||||||
|
@ -378,6 +378,11 @@ PromisedQueryPtr ClientManager::get_webhook_restore_query(td::Slice token, td::S
|
|||||||
parser.skip('/');
|
parser.skip('/');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (parser.try_skip("#secret")) {
|
||||||
|
args.emplace_back(add_string("secret_token"), add_string(parser.read_till('/')));
|
||||||
|
parser.skip('/');
|
||||||
|
}
|
||||||
|
|
||||||
if (parser.try_skip("#allow")) {
|
if (parser.try_skip("#allow")) {
|
||||||
args.emplace_back(add_string("allowed_updates"), add_string(parser.read_till('/')));
|
args.emplace_back(add_string("allowed_updates"), add_string(parser.read_till('/')));
|
||||||
parser.skip('/');
|
parser.skip('/');
|
||||||
|
@ -42,7 +42,7 @@ std::atomic<td::uint64> WebhookActor::total_connections_count_{0};
|
|||||||
|
|
||||||
WebhookActor::WebhookActor(td::ActorShared<Callback> callback, td::int64 tqueue_id, td::HttpUrl url,
|
WebhookActor::WebhookActor(td::ActorShared<Callback> callback, td::int64 tqueue_id, td::HttpUrl url,
|
||||||
td::string cert_path, td::int32 max_connections, bool from_db_flag,
|
td::string cert_path, td::int32 max_connections, bool from_db_flag,
|
||||||
td::string cached_ip_address, bool fix_ip_address,
|
td::string cached_ip_address, bool fix_ip_address, td::string secret_token,
|
||||||
std::shared_ptr<const ClientParameters> parameters)
|
std::shared_ptr<const ClientParameters> parameters)
|
||||||
: callback_(std::move(callback))
|
: callback_(std::move(callback))
|
||||||
, tqueue_id_(tqueue_id)
|
, tqueue_id_(tqueue_id)
|
||||||
@ -51,7 +51,8 @@ WebhookActor::WebhookActor(td::ActorShared<Callback> callback, td::int64 tqueue_
|
|||||||
, parameters_(std::move(parameters))
|
, parameters_(std::move(parameters))
|
||||||
, fix_ip_address_(fix_ip_address)
|
, fix_ip_address_(fix_ip_address)
|
||||||
, from_db_flag_(from_db_flag)
|
, from_db_flag_(from_db_flag)
|
||||||
, max_connections_(max_connections) {
|
, max_connections_(max_connections)
|
||||||
|
, secret_token_(std::move(secret_token)) {
|
||||||
CHECK(max_connections_ > 0);
|
CHECK(max_connections_ > 0);
|
||||||
|
|
||||||
if (!cached_ip_address.empty()) {
|
if (!cached_ip_address.empty()) {
|
||||||
@ -539,6 +540,9 @@ td::Status WebhookActor::send_update() {
|
|||||||
if (!url_.userinfo_.empty()) {
|
if (!url_.userinfo_.empty()) {
|
||||||
hc.add_header("Authorization", PSLICE() << "Basic " << td::base64_encode(url_.userinfo_));
|
hc.add_header("Authorization", PSLICE() << "Basic " << td::base64_encode(url_.userinfo_));
|
||||||
}
|
}
|
||||||
|
if (!secret_token_.empty()) {
|
||||||
|
hc.add_header("X-Telegram-Bot-Api-Secret-Token", secret_token_);
|
||||||
|
}
|
||||||
hc.set_content_type("application/json");
|
hc.set_content_type("application/json");
|
||||||
hc.set_content_size(body.size());
|
hc.set_content_size(body.size());
|
||||||
hc.set_keep_alive();
|
hc.set_keep_alive();
|
||||||
|
@ -54,7 +54,7 @@ class WebhookActor final : public td::HttpOutboundConnection::Callback {
|
|||||||
|
|
||||||
WebhookActor(td::ActorShared<Callback> callback, td::int64 tqueue_id, td::HttpUrl url, td::string cert_path,
|
WebhookActor(td::ActorShared<Callback> callback, td::int64 tqueue_id, td::HttpUrl url, td::string cert_path,
|
||||||
td::int32 max_connections, bool from_db_flag, td::string cached_ip_address, bool fix_ip_address,
|
td::int32 max_connections, bool from_db_flag, td::string cached_ip_address, bool fix_ip_address,
|
||||||
std::shared_ptr<const ClientParameters> parameters);
|
td::string secret_token, std::shared_ptr<const ClientParameters> parameters);
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
@ -163,6 +163,7 @@ class WebhookActor final : public td::HttpOutboundConnection::Callback {
|
|||||||
td::vector<td::BufferedFd<td::SocketFd>> ready_sockets_;
|
td::vector<td::BufferedFd<td::SocketFd>> ready_sockets_;
|
||||||
|
|
||||||
td::int32 max_connections_ = 0;
|
td::int32 max_connections_ = 0;
|
||||||
|
td::string secret_token_;
|
||||||
td::Container<Connection> connections_;
|
td::Container<Connection> connections_;
|
||||||
td::ListNode ready_connections_;
|
td::ListNode ready_connections_;
|
||||||
td::FloodControlFast active_new_connection_flood_;
|
td::FloodControlFast active_new_connection_flood_;
|
||||||
|
Loading…
Reference in New Issue
Block a user