From d19b659337b6d924f43fe78a3208069805d327fa Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 31 Jul 2023 19:16:24 +0300 Subject: [PATCH] Simplify JSON object processing in NotificationManager. --- td/telegram/NotificationManager.cpp | 147 +++++++++++----------------- 1 file changed, 56 insertions(+), 91 deletions(-) diff --git a/td/telegram/NotificationManager.cpp b/td/telegram/NotificationManager.cpp index 5ec04d6ed..6c016528a 100644 --- a/td/telegram/NotificationManager.cpp +++ b/td/telegram/NotificationManager.cpp @@ -3023,59 +3023,45 @@ Status NotificationManager::process_push_notification_payload(string payload, bo data = std::move(data_data.get_object()); } - string loc_key; - JsonObject custom; - string announcement_message_text; - vector loc_args; - string sender_name; - for (auto &field_value : data.field_values_) { - if (field_value.first == "loc_key") { - if (field_value.second.type() != JsonValue::Type::String) { - return Status::Error("Expected loc_key as a String"); - } - loc_key = field_value.second.get_string().str(); - } else if (field_value.first == "loc_args") { - if (field_value.second.type() != JsonValue::Type::Array) { - return Status::Error("Expected loc_args as an Array"); - } - loc_args.reserve(field_value.second.get_array().size()); - for (auto &arg : field_value.second.get_array()) { - if (arg.type() != JsonValue::Type::String) { - return Status::Error("Expected loc_arg as a String"); - } - loc_args.push_back(arg.get_string().str()); - } - } else if (field_value.first == "custom") { - if (field_value.second.type() != JsonValue::Type::Object) { - return Status::Error("Expected custom as an Object"); - } - custom = std::move(field_value.second.get_object()); - } else if (field_value.first == "message") { - if (field_value.second.type() != JsonValue::Type::String) { - return Status::Error("Expected announcement message text as a String"); - } - announcement_message_text = field_value.second.get_string().str(); - } else if (field_value.first == "google.sent_time") { - TRY_RESULT(google_sent_time, data.get_optional_long_field("google.sent_time")); - google_sent_time /= 1000; - if (sent_date - 28 * 86400 <= google_sent_time && google_sent_time <= sent_date + 5) { - sent_date = narrow_cast(google_sent_time); - } - } - } - + TRY_RESULT(loc_key, data.get_required_string_field("loc_key")); if (!clean_input_string(loc_key)) { return Status::Error(PSLICE() << "Receive invalid loc_key " << format::escaped(loc_key)); } if (loc_key.empty()) { return Status::Error("Receive empty loc_key"); } - for (auto &loc_arg : loc_args) { - if (!clean_input_string(loc_arg)) { - return Status::Error(PSLICE() << "Receive invalid loc_arg " << format::escaped(loc_arg)); + + vector loc_args; + TRY_RESULT(loc_args_array, data.extract_optional_field("loc_args", JsonValue::Type::Array)); + if (loc_args_array.type() == JsonValue::Type::Array) { + loc_args.reserve(loc_args_array.get_array().size()); + for (auto &arg : loc_args_array.get_array()) { + if (arg.type() != JsonValue::Type::String) { + return Status::Error("Expected loc_arg as a String"); + } + auto loc_arg = arg.get_string().str(); + if (!clean_input_string(loc_arg)) { + return Status::Error(PSLICE() << "Receive invalid loc_arg " << format::escaped(loc_arg)); + } + loc_args.push_back(std::move(loc_arg)); } } + JsonObject custom; + TRY_RESULT(custom_value, data.extract_optional_field("custom", JsonValue::Type::Object)); + if (custom_value.type() == JsonValue::Type::Object) { + custom = std::move(custom_value.get_object()); + } + + TRY_RESULT(google_sent_time, data.get_optional_long_field("google.sent_time")); + if (google_sent_time > 0) { + google_sent_time /= 1000; + if (sent_date - 28 * 86400 <= google_sent_time && google_sent_time <= sent_date + 5) { + sent_date = narrow_cast(google_sent_time); + } + } + + TRY_RESULT(announcement_message_text, data.get_optional_string_field("message")); if (loc_key == "MESSAGE_ANNOUNCEMENT") { if (announcement_message_text.empty()) { return Status::Error("Receive empty announcement message text"); @@ -3302,6 +3288,7 @@ Status NotificationManager::process_push_notification_payload(string payload, bo } loc_key = loc_key.substr(8); } + string sender_name; if (begins_with(loc_key, "CHAT_")) { auto dialog_type = dialog_id.get_type(); if (dialog_type != DialogType::Chat && dialog_type != DialogType::Channel) { @@ -3972,38 +3959,24 @@ Result NotificationManager::get_push_receiver_id(string payload) { data = std::move(data_data.get_object()); } - for (auto &field_value : data.field_values_) { - if (field_value.first == "p") { - auto encrypted_payload = std::move(field_value.second); - if (encrypted_payload.type() != JsonValue::Type::String) { - return Status::Error(400, "Expected encrypted payload as a String"); - } - Slice encrypted_data = encrypted_payload.get_string(); - if (encrypted_data.size() < 12) { - return Status::Error(400, "Encrypted payload is too small"); - } - auto r_decoded = base64url_decode(encrypted_data.substr(0, 12)); - if (r_decoded.is_error()) { - return Status::Error(400, "Failed to base64url-decode payload"); - } - CHECK(r_decoded.ok().size() == 9); - return as(r_decoded.ok().c_str()); + if (data.has_field("p")) { + TRY_RESULT(encrypted_data, data.get_required_string_field("p")); + if (encrypted_data.size() < 12) { + return Status::Error(400, "Encrypted payload is too small"); } - if (field_value.first == "user_id") { - auto user_id = std::move(field_value.second); - if (user_id.type() != JsonValue::Type::String && user_id.type() != JsonValue::Type::Number) { - return Status::Error(400, "Expected user_id as a String or a Number"); - } - Slice user_id_str = user_id.type() == JsonValue::Type::String ? user_id.get_string() : user_id.get_number(); - auto r_user_id = to_integer_safe(user_id_str); - if (r_user_id.is_error()) { - return Status::Error(400, PSLICE() << "Failed to get user_id from " << user_id_str); - } - if (r_user_id.ok() <= 0) { - return Status::Error(400, PSLICE() << "Receive wrong user_id " << user_id_str); - } - return r_user_id.ok(); + auto r_decoded = base64url_decode(encrypted_data.substr(0, 12)); + if (r_decoded.is_error()) { + return Status::Error(400, "Failed to base64url-decode payload"); } + CHECK(r_decoded.ok().size() == 9); + return as(r_decoded.ok().c_str()); + } + if (data.has_field("user_id")) { + TRY_RESULT(user_id, data.get_required_long_field("user_id")); + if (user_id <= 0) { + return Status::Error(400, PSLICE() << "Receive wrong user_id " << user_id); + } + return user_id; } return static_cast(0); @@ -4020,24 +3993,16 @@ Result NotificationManager::decrypt_push(int64 encryption_key_id, string return Status::Error(400, "Expected JSON object"); } - for (auto &field_value : json_value.get_object().field_values_) { - if (field_value.first == "p") { - auto encrypted_payload = std::move(field_value.second); - if (encrypted_payload.type() != JsonValue::Type::String) { - return Status::Error(400, "Expected encrypted payload as a String"); - } - Slice encrypted_data = encrypted_payload.get_string(); - if (encrypted_data.size() < 12) { - return Status::Error(400, "Encrypted payload is too small"); - } - auto r_decoded = base64url_decode(encrypted_data); - if (r_decoded.is_error()) { - return Status::Error(400, "Failed to base64url-decode payload"); - } - return decrypt_push_payload(encryption_key_id, std::move(encryption_key), r_decoded.move_as_ok()); - } + const auto &object = json_value.get_object(); + TRY_RESULT(encrypted_data, object.get_required_string_field("p")); + if (encrypted_data.size() < 12) { + return Status::Error(400, "Encrypted payload is too small"); } - return Status::Error(400, "No 'p'(payload) field found in the push notification"); + auto r_decoded = base64url_decode(encrypted_data); + if (r_decoded.is_error()) { + return Status::Error(400, "Failed to base64url-decode payload"); + } + return decrypt_push_payload(encryption_key_id, std::move(encryption_key), r_decoded.move_as_ok()); } Result NotificationManager::decrypt_push_payload(int64 encryption_key_id, string encryption_key,