From 586586d50c024faac75f645d2b2468566c79d8c6 Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 8 May 2023 13:50:51 +0300 Subject: [PATCH] Move UserPrivacySettingRule to a separate header. --- CMakeLists.txt | 2 + td/telegram/PrivacyManager.cpp | 285 +---------------------- td/telegram/PrivacyManager.h | 72 +----- td/telegram/UserPrivacySettingRule.cpp | 304 +++++++++++++++++++++++++ td/telegram/UserPrivacySettingRule.h | 89 ++++++++ 5 files changed, 397 insertions(+), 355 deletions(-) create mode 100644 td/telegram/UserPrivacySettingRule.cpp create mode 100644 td/telegram/UserPrivacySettingRule.h diff --git a/CMakeLists.txt b/CMakeLists.txt index eaba216e1..068e947b5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -481,6 +481,7 @@ set(TDLIB_SOURCE td/telegram/TranslationManager.cpp td/telegram/UpdatesManager.cpp td/telegram/Usernames.cpp + td/telegram/UserPrivacySettingRule.cpp td/telegram/Venue.cpp td/telegram/VideoNotesManager.cpp td/telegram/VideosManager.cpp @@ -773,6 +774,7 @@ set(TDLIB_SOURCE td/telegram/UpdatesManager.h td/telegram/UserId.h td/telegram/Usernames.h + td/telegram/UserPrivacySettingRule.h td/telegram/Venue.h td/telegram/Version.h td/telegram/VideoNotesManager.h diff --git a/td/telegram/PrivacyManager.cpp b/td/telegram/PrivacyManager.cpp index 03453b2aa..c56f22ff9 100644 --- a/td/telegram/PrivacyManager.cpp +++ b/td/telegram/PrivacyManager.cpp @@ -6,15 +6,12 @@ // #include "td/telegram/PrivacyManager.h" -#include "td/telegram/ChannelId.h" -#include "td/telegram/ChatId.h" #include "td/telegram/ContactsManager.h" -#include "td/telegram/DialogId.h" #include "td/telegram/Global.h" -#include "td/telegram/MessagesManager.h" #include "td/telegram/net/NetQueryCreator.h" #include "td/telegram/net/NetQueryDispatcher.h" #include "td/telegram/Td.h" +#include "td/telegram/UserId.h" #include "td/utils/algorithm.h" #include "td/utils/logging.h" @@ -163,286 +160,6 @@ PrivacyManager::UserPrivacySetting::UserPrivacySetting(const td_api::UserPrivacy } } -void PrivacyManager::UserPrivacySettingRule::set_chat_ids(const vector &dialog_ids) { - chat_ids_.clear(); - auto td = G()->td().get_actor_unsafe(); - for (auto dialog_id_int : dialog_ids) { - DialogId dialog_id(dialog_id_int); - if (!td->messages_manager_->have_dialog_force(dialog_id, "UserPrivacySettingRule::set_chat_ids")) { - LOG(ERROR) << "Ignore not found " << dialog_id; - continue; - } - - switch (dialog_id.get_type()) { - case DialogType::Chat: - chat_ids_.push_back(dialog_id.get_chat_id().get()); - break; - case DialogType::Channel: { - auto channel_id = dialog_id.get_channel_id(); - if (!td->contacts_manager_->is_megagroup_channel(channel_id)) { - LOG(ERROR) << "Ignore broadcast " << channel_id; - break; - } - chat_ids_.push_back(channel_id.get()); - break; - } - default: - LOG(ERROR) << "Ignore " << dialog_id; - } - } -} - -PrivacyManager::UserPrivacySettingRule::UserPrivacySettingRule(const td_api::UserPrivacySettingRule &rule) { - switch (rule.get_id()) { - case td_api::userPrivacySettingRuleAllowContacts::ID: - type_ = Type::AllowContacts; - break; - case td_api::userPrivacySettingRuleAllowCloseFriends::ID: - type_ = Type::AllowCloseFriends; - break; - case td_api::userPrivacySettingRuleAllowAll::ID: - type_ = Type::AllowAll; - break; - case td_api::userPrivacySettingRuleAllowUsers::ID: - type_ = Type::AllowUsers; - user_ids_ = UserId::get_user_ids(static_cast(rule).user_ids_); - break; - case td_api::userPrivacySettingRuleAllowChatMembers::ID: - type_ = Type::AllowChatParticipants; - set_chat_ids(static_cast(rule).chat_ids_); - break; - case td_api::userPrivacySettingRuleRestrictContacts::ID: - type_ = Type::RestrictContacts; - break; - case td_api::userPrivacySettingRuleRestrictAll::ID: - type_ = Type::RestrictAll; - break; - case td_api::userPrivacySettingRuleRestrictUsers::ID: - type_ = Type::RestrictUsers; - user_ids_ = - UserId::get_user_ids(static_cast(rule).user_ids_); - break; - case td_api::userPrivacySettingRuleRestrictChatMembers::ID: - type_ = Type::RestrictChatParticipants; - set_chat_ids(static_cast(rule).chat_ids_); - break; - default: - UNREACHABLE(); - } -} - -PrivacyManager::UserPrivacySettingRule::UserPrivacySettingRule(const telegram_api::PrivacyRule &rule) { - switch (rule.get_id()) { - case telegram_api::privacyValueAllowContacts::ID: - type_ = Type::AllowContacts; - break; - case telegram_api::privacyValueAllowCloseFriends::ID: - type_ = Type::AllowCloseFriends; - break; - case telegram_api::privacyValueAllowAll::ID: - type_ = Type::AllowAll; - break; - case telegram_api::privacyValueAllowUsers::ID: - type_ = Type::AllowUsers; - user_ids_ = UserId::get_user_ids(static_cast(rule).users_); - break; - case telegram_api::privacyValueAllowChatParticipants::ID: - type_ = Type::AllowChatParticipants; - chat_ids_ = static_cast(rule).chats_; - break; - case telegram_api::privacyValueDisallowContacts::ID: - type_ = Type::RestrictContacts; - break; - case telegram_api::privacyValueDisallowAll::ID: - type_ = Type::RestrictAll; - break; - case telegram_api::privacyValueDisallowUsers::ID: - type_ = Type::RestrictUsers; - user_ids_ = UserId::get_user_ids(static_cast(rule).users_); - break; - case telegram_api::privacyValueDisallowChatParticipants::ID: - type_ = Type::RestrictChatParticipants; - chat_ids_ = static_cast(rule).chats_; - break; - default: - UNREACHABLE(); - } -} - -tl_object_ptr -PrivacyManager::UserPrivacySettingRule::get_user_privacy_setting_rule_object() const { - switch (type_) { - case Type::AllowContacts: - return make_tl_object(); - case Type::AllowCloseFriends: - return make_tl_object(); - case Type::AllowAll: - return make_tl_object(); - case Type::AllowUsers: - return make_tl_object(UserId::get_input_user_ids(user_ids_)); - case Type::AllowChatParticipants: - return make_tl_object(chat_ids_as_dialog_ids()); - case Type::RestrictContacts: - return make_tl_object(); - case Type::RestrictAll: - return make_tl_object(); - case Type::RestrictUsers: - return make_tl_object(UserId::get_input_user_ids(user_ids_)); - case Type::RestrictChatParticipants: - return make_tl_object(chat_ids_as_dialog_ids()); - default: - UNREACHABLE(); - } -} - -tl_object_ptr PrivacyManager::UserPrivacySettingRule::get_input_privacy_rule() const { - switch (type_) { - case Type::AllowContacts: - return make_tl_object(); - case Type::AllowCloseFriends: - return make_tl_object(); - case Type::AllowAll: - return make_tl_object(); - case Type::AllowUsers: - return make_tl_object(get_input_users()); - case Type::AllowChatParticipants: - return make_tl_object(vector{chat_ids_}); - case Type::RestrictContacts: - return make_tl_object(); - case Type::RestrictAll: - return make_tl_object(); - case Type::RestrictUsers: - return make_tl_object(get_input_users()); - case Type::RestrictChatParticipants: - return make_tl_object(vector{chat_ids_}); - default: - UNREACHABLE(); - } -} - -Result PrivacyManager::UserPrivacySettingRule::get_user_privacy_setting_rule( - tl_object_ptr rule) { - CHECK(rule != nullptr); - UserPrivacySettingRule result(*rule); - auto td = G()->td().get_actor_unsafe(); - for (auto user_id : result.user_ids_) { - if (!td->contacts_manager_->have_user(user_id)) { - return Status::Error(500, "Receive inaccessible user from the server"); - } - } - for (auto chat_id_int : result.chat_ids_) { - ChatId chat_id(chat_id_int); - DialogId dialog_id(chat_id); - if (!td->contacts_manager_->have_chat(chat_id)) { - ChannelId channel_id(chat_id_int); - dialog_id = DialogId(channel_id); - if (!td->contacts_manager_->have_channel(channel_id)) { - return Status::Error(500, "Receive inaccessible chat from the server"); - } - } - td->messages_manager_->force_create_dialog(dialog_id, "UserPrivacySettingRule"); - } - return result; -} - -vector> PrivacyManager::UserPrivacySettingRule::get_input_users() const { - vector> result; - for (auto user_id : user_ids_) { - auto r_input_user = G()->td().get_actor_unsafe()->contacts_manager_->get_input_user(user_id); - if (r_input_user.is_ok()) { - result.push_back(r_input_user.move_as_ok()); - } else { - LOG(ERROR) << "Have no access to " << user_id; - } - } - return result; -} - -vector PrivacyManager::UserPrivacySettingRule::chat_ids_as_dialog_ids() const { - vector result; - auto td = G()->td().get_actor_unsafe(); - for (auto chat_id_int : chat_ids_) { - ChatId chat_id(chat_id_int); - DialogId dialog_id(chat_id); - if (!td->contacts_manager_->have_chat(chat_id)) { - ChannelId channel_id(chat_id_int); - dialog_id = DialogId(channel_id); - CHECK(td->contacts_manager_->have_channel(channel_id)); - } - CHECK(td->messages_manager_->have_dialog(dialog_id)); - result.push_back(td->messages_manager_->get_chat_id_object(dialog_id, "UserPrivacySettingRule")); - } - return result; -} - -vector PrivacyManager::UserPrivacySettingRule::get_restricted_user_ids() const { - if (type_ == Type::RestrictUsers) { - return user_ids_; - } - return {}; -} - -Result PrivacyManager::UserPrivacySettingRules::get_user_privacy_setting_rules( - tl_object_ptr rules) { - G()->td().get_actor_unsafe()->contacts_manager_->on_get_users(std::move(rules->users_), "on get privacy rules"); - G()->td().get_actor_unsafe()->contacts_manager_->on_get_chats(std::move(rules->chats_), "on get privacy rules"); - return get_user_privacy_setting_rules(std::move(rules->rules_)); -} - -Result PrivacyManager::UserPrivacySettingRules::get_user_privacy_setting_rules( - vector> rules) { - UserPrivacySettingRules result; - for (auto &rule : rules) { - TRY_RESULT(new_rule, UserPrivacySettingRule::get_user_privacy_setting_rule(std::move(rule))); - result.rules_.push_back(new_rule); - } - if (!result.rules_.empty() && result.rules_.back().get_user_privacy_setting_rule_object()->get_id() == - td_api::userPrivacySettingRuleRestrictAll::ID) { - result.rules_.pop_back(); - } - return result; -} - -Result PrivacyManager::UserPrivacySettingRules::get_user_privacy_setting_rules( - tl_object_ptr rules) { - if (rules == nullptr) { - return Status::Error(400, "UserPrivacySettingRules must be non-empty"); - } - UserPrivacySettingRules result; - for (auto &rule : rules->rules_) { - if (rule == nullptr) { - return Status::Error(400, "UserPrivacySettingRule must be non-empty"); - } - result.rules_.emplace_back(*rule); - } - return result; -} - -tl_object_ptr -PrivacyManager::UserPrivacySettingRules::get_user_privacy_setting_rules_object() const { - return make_tl_object( - transform(rules_, [](const auto &rule) { return rule.get_user_privacy_setting_rule_object(); })); -} - -vector> PrivacyManager::UserPrivacySettingRules::get_input_privacy_rules() - const { - auto result = transform(rules_, [](const auto &rule) { return rule.get_input_privacy_rule(); }); - if (!result.empty() && result.back()->get_id() == telegram_api::inputPrivacyValueDisallowAll::ID) { - result.pop_back(); - } - return result; -} - -vector PrivacyManager::UserPrivacySettingRules::get_restricted_user_ids() const { - vector result; - for (auto &rule : rules_) { - combine(result, rule.get_restricted_user_ids()); - } - std::sort(result.begin(), result.end(), [](UserId lhs, UserId rhs) { return lhs.get() < rhs.get(); }); - result.erase(std::unique(result.begin(), result.end()), result.end()); - return result; -} - void PrivacyManager::get_privacy(tl_object_ptr key, Promise> promise) { auto r_user_privacy_setting = UserPrivacySetting::get_user_privacy_setting(std::move(key)); diff --git a/td/telegram/PrivacyManager.h b/td/telegram/PrivacyManager.h index 2372d2827..06f2565f9 100644 --- a/td/telegram/PrivacyManager.h +++ b/td/telegram/PrivacyManager.h @@ -9,7 +9,7 @@ #include "td/telegram/net/NetQuery.h" #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" -#include "td/telegram/UserId.h" +#include "td/telegram/UserPrivacySettingRule.h" #include "td/actor/actor.h" @@ -70,76 +70,6 @@ class PrivacyManager final : public NetQueryCallback { explicit UserPrivacySetting(const td_api::UserPrivacySetting &key); }; - class UserPrivacySettingRule { - public: - UserPrivacySettingRule() = default; - - explicit UserPrivacySettingRule(const td_api::UserPrivacySettingRule &rule); - - static Result get_user_privacy_setting_rule(tl_object_ptr rule); - - tl_object_ptr get_user_privacy_setting_rule_object() const; - - tl_object_ptr get_input_privacy_rule() const; - - bool operator==(const UserPrivacySettingRule &other) const { - return type_ == other.type_ && user_ids_ == other.user_ids_ && chat_ids_ == other.chat_ids_; - } - - vector get_restricted_user_ids() const; - - private: - enum class Type : int32 { - AllowContacts, - AllowCloseFriends, - AllowAll, - AllowUsers, - AllowChatParticipants, - RestrictContacts, - RestrictAll, - RestrictUsers, - RestrictChatParticipants - } type_ = Type::RestrictAll; - - vector user_ids_; - vector chat_ids_; - - vector> get_input_users() const; - - void set_chat_ids(const vector &dialog_ids); - - vector chat_ids_as_dialog_ids() const; - - explicit UserPrivacySettingRule(const telegram_api::PrivacyRule &rule); - }; - - class UserPrivacySettingRules { - public: - UserPrivacySettingRules() = default; - - static Result get_user_privacy_setting_rules( - tl_object_ptr rules); - - static Result get_user_privacy_setting_rules( - vector> rules); - - static Result get_user_privacy_setting_rules( - tl_object_ptr rules); - - tl_object_ptr get_user_privacy_setting_rules_object() const; - - vector> get_input_privacy_rules() const; - - bool operator==(const UserPrivacySettingRules &other) const { - return rules_ == other.rules_; - } - - vector get_restricted_user_ids() const; - - private: - vector rules_; - }; - ActorShared<> parent_; struct PrivacyInfo { diff --git a/td/telegram/UserPrivacySettingRule.cpp b/td/telegram/UserPrivacySettingRule.cpp new file mode 100644 index 000000000..b81f09b61 --- /dev/null +++ b/td/telegram/UserPrivacySettingRule.cpp @@ -0,0 +1,304 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/UserPrivacySettingRule.h" + +#include "td/telegram/ChannelId.h" +#include "td/telegram/ChatId.h" +#include "td/telegram/ContactsManager.h" +#include "td/telegram/DialogId.h" +#include "td/telegram/Global.h" +#include "td/telegram/MessagesManager.h" +#include "td/telegram/Td.h" + +#include "td/utils/algorithm.h" +#include "td/utils/logging.h" + +#include + +namespace td { + +void UserPrivacySettingRule::set_chat_ids(const vector &dialog_ids) { + chat_ids_.clear(); + auto td = G()->td().get_actor_unsafe(); + for (auto dialog_id_int : dialog_ids) { + DialogId dialog_id(dialog_id_int); + if (!td->messages_manager_->have_dialog_force(dialog_id, "UserPrivacySettingRule::set_chat_ids")) { + LOG(ERROR) << "Ignore not found " << dialog_id; + continue; + } + + switch (dialog_id.get_type()) { + case DialogType::Chat: + chat_ids_.push_back(dialog_id.get_chat_id().get()); + break; + case DialogType::Channel: { + auto channel_id = dialog_id.get_channel_id(); + if (!td->contacts_manager_->is_megagroup_channel(channel_id)) { + LOG(ERROR) << "Ignore broadcast " << channel_id; + break; + } + chat_ids_.push_back(channel_id.get()); + break; + } + default: + LOG(ERROR) << "Ignore " << dialog_id; + } + } +} + +UserPrivacySettingRule::UserPrivacySettingRule(const td_api::UserPrivacySettingRule &rule) { + switch (rule.get_id()) { + case td_api::userPrivacySettingRuleAllowContacts::ID: + type_ = Type::AllowContacts; + break; + case td_api::userPrivacySettingRuleAllowCloseFriends::ID: + type_ = Type::AllowCloseFriends; + break; + case td_api::userPrivacySettingRuleAllowAll::ID: + type_ = Type::AllowAll; + break; + case td_api::userPrivacySettingRuleAllowUsers::ID: + type_ = Type::AllowUsers; + user_ids_ = UserId::get_user_ids(static_cast(rule).user_ids_); + break; + case td_api::userPrivacySettingRuleAllowChatMembers::ID: + type_ = Type::AllowChatParticipants; + set_chat_ids(static_cast(rule).chat_ids_); + break; + case td_api::userPrivacySettingRuleRestrictContacts::ID: + type_ = Type::RestrictContacts; + break; + case td_api::userPrivacySettingRuleRestrictAll::ID: + type_ = Type::RestrictAll; + break; + case td_api::userPrivacySettingRuleRestrictUsers::ID: + type_ = Type::RestrictUsers; + user_ids_ = + UserId::get_user_ids(static_cast(rule).user_ids_); + break; + case td_api::userPrivacySettingRuleRestrictChatMembers::ID: + type_ = Type::RestrictChatParticipants; + set_chat_ids(static_cast(rule).chat_ids_); + break; + default: + UNREACHABLE(); + } +} + +UserPrivacySettingRule::UserPrivacySettingRule(const telegram_api::PrivacyRule &rule) { + switch (rule.get_id()) { + case telegram_api::privacyValueAllowContacts::ID: + type_ = Type::AllowContacts; + break; + case telegram_api::privacyValueAllowCloseFriends::ID: + type_ = Type::AllowCloseFriends; + break; + case telegram_api::privacyValueAllowAll::ID: + type_ = Type::AllowAll; + break; + case telegram_api::privacyValueAllowUsers::ID: + type_ = Type::AllowUsers; + user_ids_ = UserId::get_user_ids(static_cast(rule).users_); + break; + case telegram_api::privacyValueAllowChatParticipants::ID: + type_ = Type::AllowChatParticipants; + chat_ids_ = static_cast(rule).chats_; + break; + case telegram_api::privacyValueDisallowContacts::ID: + type_ = Type::RestrictContacts; + break; + case telegram_api::privacyValueDisallowAll::ID: + type_ = Type::RestrictAll; + break; + case telegram_api::privacyValueDisallowUsers::ID: + type_ = Type::RestrictUsers; + user_ids_ = UserId::get_user_ids(static_cast(rule).users_); + break; + case telegram_api::privacyValueDisallowChatParticipants::ID: + type_ = Type::RestrictChatParticipants; + chat_ids_ = static_cast(rule).chats_; + break; + default: + UNREACHABLE(); + } +} + +td_api::object_ptr UserPrivacySettingRule::get_user_privacy_setting_rule_object() + const { + switch (type_) { + case Type::AllowContacts: + return make_tl_object(); + case Type::AllowCloseFriends: + return make_tl_object(); + case Type::AllowAll: + return make_tl_object(); + case Type::AllowUsers: + return make_tl_object(UserId::get_input_user_ids(user_ids_)); + case Type::AllowChatParticipants: + return make_tl_object(chat_ids_as_dialog_ids()); + case Type::RestrictContacts: + return make_tl_object(); + case Type::RestrictAll: + return make_tl_object(); + case Type::RestrictUsers: + return make_tl_object(UserId::get_input_user_ids(user_ids_)); + case Type::RestrictChatParticipants: + return make_tl_object(chat_ids_as_dialog_ids()); + default: + UNREACHABLE(); + } +} + +telegram_api::object_ptr UserPrivacySettingRule::get_input_privacy_rule() const { + switch (type_) { + case Type::AllowContacts: + return make_tl_object(); + case Type::AllowCloseFriends: + return make_tl_object(); + case Type::AllowAll: + return make_tl_object(); + case Type::AllowUsers: + return make_tl_object(get_input_users()); + case Type::AllowChatParticipants: + return make_tl_object(vector{chat_ids_}); + case Type::RestrictContacts: + return make_tl_object(); + case Type::RestrictAll: + return make_tl_object(); + case Type::RestrictUsers: + return make_tl_object(get_input_users()); + case Type::RestrictChatParticipants: + return make_tl_object(vector{chat_ids_}); + default: + UNREACHABLE(); + } +} + +Result UserPrivacySettingRule::get_user_privacy_setting_rule( + telegram_api::object_ptr rule) { + CHECK(rule != nullptr); + UserPrivacySettingRule result(*rule); + auto td = G()->td().get_actor_unsafe(); + for (auto user_id : result.user_ids_) { + if (!td->contacts_manager_->have_user(user_id)) { + return Status::Error(500, "Receive inaccessible user from the server"); + } + } + for (auto chat_id_int : result.chat_ids_) { + ChatId chat_id(chat_id_int); + DialogId dialog_id(chat_id); + if (!td->contacts_manager_->have_chat(chat_id)) { + ChannelId channel_id(chat_id_int); + dialog_id = DialogId(channel_id); + if (!td->contacts_manager_->have_channel(channel_id)) { + return Status::Error(500, "Receive inaccessible chat from the server"); + } + } + td->messages_manager_->force_create_dialog(dialog_id, "UserPrivacySettingRule"); + } + return result; +} + +vector> UserPrivacySettingRule::get_input_users() const { + vector> result; + for (auto user_id : user_ids_) { + auto r_input_user = G()->td().get_actor_unsafe()->contacts_manager_->get_input_user(user_id); + if (r_input_user.is_ok()) { + result.push_back(r_input_user.move_as_ok()); + } else { + LOG(ERROR) << "Have no access to " << user_id; + } + } + return result; +} + +vector UserPrivacySettingRule::chat_ids_as_dialog_ids() const { + vector result; + auto td = G()->td().get_actor_unsafe(); + for (auto chat_id_int : chat_ids_) { + ChatId chat_id(chat_id_int); + DialogId dialog_id(chat_id); + if (!td->contacts_manager_->have_chat(chat_id)) { + ChannelId channel_id(chat_id_int); + dialog_id = DialogId(channel_id); + CHECK(td->contacts_manager_->have_channel(channel_id)); + } + CHECK(td->messages_manager_->have_dialog(dialog_id)); + result.push_back(td->messages_manager_->get_chat_id_object(dialog_id, "UserPrivacySettingRule")); + } + return result; +} + +vector UserPrivacySettingRule::get_restricted_user_ids() const { + if (type_ == Type::RestrictUsers) { + return user_ids_; + } + return {}; +} + +Result UserPrivacySettingRules::get_user_privacy_setting_rules( + telegram_api::object_ptr rules) { + G()->td().get_actor_unsafe()->contacts_manager_->on_get_users(std::move(rules->users_), "on get privacy rules"); + G()->td().get_actor_unsafe()->contacts_manager_->on_get_chats(std::move(rules->chats_), "on get privacy rules"); + return get_user_privacy_setting_rules(std::move(rules->rules_)); +} + +Result UserPrivacySettingRules::get_user_privacy_setting_rules( + vector> rules) { + UserPrivacySettingRules result; + for (auto &rule : rules) { + TRY_RESULT(new_rule, UserPrivacySettingRule::get_user_privacy_setting_rule(std::move(rule))); + result.rules_.push_back(new_rule); + } + if (!result.rules_.empty() && result.rules_.back().get_user_privacy_setting_rule_object()->get_id() == + td_api::userPrivacySettingRuleRestrictAll::ID) { + result.rules_.pop_back(); + } + return result; +} + +Result UserPrivacySettingRules::get_user_privacy_setting_rules( + td_api::object_ptr rules) { + if (rules == nullptr) { + return Status::Error(400, "UserPrivacySettingRules must be non-empty"); + } + UserPrivacySettingRules result; + for (auto &rule : rules->rules_) { + if (rule == nullptr) { + return Status::Error(400, "UserPrivacySettingRule must be non-empty"); + } + result.rules_.emplace_back(*rule); + } + return result; +} + +td_api::object_ptr UserPrivacySettingRules::get_user_privacy_setting_rules_object() + const { + return make_tl_object( + transform(rules_, [](const auto &rule) { return rule.get_user_privacy_setting_rule_object(); })); +} + +vector> UserPrivacySettingRules::get_input_privacy_rules() + const { + auto result = transform(rules_, [](const auto &rule) { return rule.get_input_privacy_rule(); }); + if (!result.empty() && result.back()->get_id() == telegram_api::inputPrivacyValueDisallowAll::ID) { + result.pop_back(); + } + return result; +} + +vector UserPrivacySettingRules::get_restricted_user_ids() const { + vector result; + for (auto &rule : rules_) { + combine(result, rule.get_restricted_user_ids()); + } + std::sort(result.begin(), result.end(), [](UserId lhs, UserId rhs) { return lhs.get() < rhs.get(); }); + result.erase(std::unique(result.begin(), result.end()), result.end()); + return result; +} + +} // namespace td diff --git a/td/telegram/UserPrivacySettingRule.h b/td/telegram/UserPrivacySettingRule.h new file mode 100644 index 000000000..4435bfdef --- /dev/null +++ b/td/telegram/UserPrivacySettingRule.h @@ -0,0 +1,89 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" +#include "td/telegram/UserId.h" + +#include "td/utils/common.h" +#include "td/utils/Status.h" + +namespace td { + +class UserPrivacySettingRule { + public: + UserPrivacySettingRule() = default; + + explicit UserPrivacySettingRule(const td_api::UserPrivacySettingRule &rule); + + static Result get_user_privacy_setting_rule( + telegram_api::object_ptr rule); + + td_api::object_ptr get_user_privacy_setting_rule_object() const; + + telegram_api::object_ptr get_input_privacy_rule() const; + + bool operator==(const UserPrivacySettingRule &other) const { + return type_ == other.type_ && user_ids_ == other.user_ids_ && chat_ids_ == other.chat_ids_; + } + + vector get_restricted_user_ids() const; + + private: + enum class Type : int32 { + AllowContacts, + AllowCloseFriends, + AllowAll, + AllowUsers, + AllowChatParticipants, + RestrictContacts, + RestrictAll, + RestrictUsers, + RestrictChatParticipants + } type_ = Type::RestrictAll; + + vector user_ids_; + vector chat_ids_; + + vector> get_input_users() const; + + void set_chat_ids(const vector &dialog_ids); + + vector chat_ids_as_dialog_ids() const; + + explicit UserPrivacySettingRule(const telegram_api::PrivacyRule &rule); +}; + +class UserPrivacySettingRules { + public: + UserPrivacySettingRules() = default; + + static Result get_user_privacy_setting_rules( + telegram_api::object_ptr rules); + + static Result get_user_privacy_setting_rules( + vector> rules); + + static Result get_user_privacy_setting_rules( + td_api::object_ptr rules); + + td_api::object_ptr get_user_privacy_setting_rules_object() const; + + vector> get_input_privacy_rules() const; + + bool operator==(const UserPrivacySettingRules &other) const { + return rules_ == other.rules_; + } + + vector get_restricted_user_ids() const; + + private: + vector rules_; +}; + +} // namespace td