Add td_api::userPrivacySettingRule{Allow,Restrict}ChatMembers.

GitOrigin-RevId: 8051f0cd177aa15c51257ba2b96117df7046f675
This commit is contained in:
levlam 2019-09-03 21:16:10 +03:00
parent 779fbb6d83
commit e70d12c751
6 changed files with 133 additions and 27 deletions

View File

@ -2234,18 +2234,24 @@ userPrivacySettingRuleAllowAll = UserPrivacySettingRule;
//@description A rule to allow all of a user's contacts to do something
userPrivacySettingRuleAllowContacts = UserPrivacySettingRule;
//@description A rule to allow certain specified users to do something @user_ids The user identifiers
//@description A rule to allow certain specified users to do something @user_ids The user identifiers, total number of users in all rules must not exceed 1000
userPrivacySettingRuleAllowUsers user_ids:vector<int32> = UserPrivacySettingRule;
//@description A rule to allow all members of certain specified basic groups and supergroups to doing something @chat_ids The chat identifiers, total number of chats in all rules must not exceed 20
userPrivacySettingRuleAllowChatMembers chat_ids:vector<int53> = UserPrivacySettingRule;
//@description A rule to restrict all users from doing something
userPrivacySettingRuleRestrictAll = UserPrivacySettingRule;
//@description A rule to restrict all contacts of a user from doing something
userPrivacySettingRuleRestrictContacts = UserPrivacySettingRule;
//@description A rule to restrict all specified users from doing something @user_ids The user identifiers
//@description A rule to restrict all specified users from doing something @user_ids The user identifiers, total number of users in all rules must not exceed 1000
userPrivacySettingRuleRestrictUsers user_ids:vector<int32> = UserPrivacySettingRule;
//@description A rule to restrict all members of specified basic groups and supergroups from doing something @chat_ids The chat identifiers, total number of chats in all rules must not exceed 20
userPrivacySettingRuleRestrictChatMembers chat_ids:vector<int53> = UserPrivacySettingRule;
//@description A list of privacy rules. Rules are matched in the specified order. The first matched rule defines the privacy setting for a given user. If no rule matches, the action is not allowed @rules A list of rules
userPrivacySettingRules rules:vector<UserPrivacySettingRule> = UserPrivacySettingRules;

Binary file not shown.

View File

@ -9,8 +9,12 @@
#include "td/telegram/td_api.h"
#include "td/telegram/telegram_api.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"
@ -129,6 +133,35 @@ PrivacyManager::UserPrivacySetting::UserPrivacySetting(const td_api::UserPrivacy
}
}
void PrivacyManager::UserPrivacySettingRule::set_chat_ids(const vector<int64> &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)) {
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_->get_channel_type(channel_id) != ChannelType::Megagroup) {
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:
@ -141,6 +174,10 @@ PrivacyManager::UserPrivacySettingRule::UserPrivacySettingRule(const td_api::Use
type_ = Type::AllowUsers;
user_ids_ = static_cast<const td_api::userPrivacySettingRuleAllowUsers &>(rule).user_ids_;
break;
case td_api::userPrivacySettingRuleAllowChatMembers::ID:
type_ = Type::AllowChatParticipants;
set_chat_ids(static_cast<const td_api::userPrivacySettingRuleAllowChatMembers &>(rule).chat_ids_);
break;
case td_api::userPrivacySettingRuleRestrictContacts::ID:
type_ = Type::RestrictContacts;
break;
@ -151,6 +188,10 @@ PrivacyManager::UserPrivacySettingRule::UserPrivacySettingRule(const td_api::Use
type_ = Type::RestrictUsers;
user_ids_ = static_cast<const td_api::userPrivacySettingRuleRestrictUsers &>(rule).user_ids_;
break;
case td_api::userPrivacySettingRuleRestrictChatMembers::ID:
type_ = Type::RestrictChatParticipants;
set_chat_ids(static_cast<const td_api::userPrivacySettingRuleRestrictChatMembers &>(rule).chat_ids_);
break;
default:
UNREACHABLE();
}
@ -168,6 +209,10 @@ PrivacyManager::UserPrivacySettingRule::UserPrivacySettingRule(const telegram_ap
type_ = Type::AllowUsers;
user_ids_ = static_cast<const telegram_api::privacyValueAllowUsers &>(rule).users_;
break;
case telegram_api::privacyValueAllowChatParticipants::ID:
type_ = Type::AllowChatParticipants;
chat_ids_ = static_cast<const telegram_api::privacyValueAllowChatParticipants &>(rule).chats_;
break;
case telegram_api::privacyValueDisallowContacts::ID:
type_ = Type::RestrictContacts;
break;
@ -178,6 +223,10 @@ PrivacyManager::UserPrivacySettingRule::UserPrivacySettingRule(const telegram_ap
type_ = Type::RestrictUsers;
user_ids_ = static_cast<const telegram_api::privacyValueDisallowUsers &>(rule).users_;
break;
case telegram_api::privacyValueDisallowChatParticipants::ID:
type_ = Type::RestrictChatParticipants;
chat_ids_ = static_cast<const telegram_api::privacyValueDisallowChatParticipants &>(rule).chats_;
break;
default:
UNREACHABLE();
}
@ -190,13 +239,17 @@ tl_object_ptr<td_api::UserPrivacySettingRule> PrivacyManager::UserPrivacySetting
case Type::AllowAll:
return make_tl_object<td_api::userPrivacySettingRuleAllowAll>();
case Type::AllowUsers:
return make_tl_object<td_api::userPrivacySettingRuleAllowUsers>(user_ids_as_td_api());
return make_tl_object<td_api::userPrivacySettingRuleAllowUsers>(vector<int32>{user_ids_});
case Type::AllowChatParticipants:
return make_tl_object<td_api::userPrivacySettingRuleAllowChatMembers>(chat_ids_as_dialog_ids());
case Type::RestrictContacts:
return make_tl_object<td_api::userPrivacySettingRuleRestrictContacts>();
case Type::RestrictAll:
return make_tl_object<td_api::userPrivacySettingRuleRestrictAll>();
case Type::RestrictUsers:
return make_tl_object<td_api::userPrivacySettingRuleRestrictUsers>(user_ids_as_td_api());
return make_tl_object<td_api::userPrivacySettingRuleRestrictUsers>(vector<int32>{user_ids_});
case Type::RestrictChatParticipants:
return make_tl_object<td_api::userPrivacySettingRuleRestrictChatMembers>(chat_ids_as_dialog_ids());
default:
UNREACHABLE();
}
@ -210,12 +263,16 @@ tl_object_ptr<telegram_api::InputPrivacyRule> PrivacyManager::UserPrivacySetting
return make_tl_object<telegram_api::inputPrivacyValueAllowAll>();
case Type::AllowUsers:
return make_tl_object<telegram_api::inputPrivacyValueAllowUsers>(user_ids_as_telegram_api());
case Type::AllowChatParticipants:
return make_tl_object<telegram_api::inputPrivacyValueAllowChatParticipants>(vector<int32>{chat_ids_});
case Type::RestrictContacts:
return make_tl_object<telegram_api::inputPrivacyValueDisallowContacts>();
case Type::RestrictAll:
return make_tl_object<telegram_api::inputPrivacyValueDisallowAll>();
case Type::RestrictUsers:
return make_tl_object<telegram_api::inputPrivacyValueDisallowUsers>(user_ids_as_telegram_api());
case Type::RestrictChatParticipants:
return make_tl_object<telegram_api::inputPrivacyValueDisallowChatParticipants>(vector<int32>{chat_ids_});
default:
UNREACHABLE();
}
@ -224,31 +281,57 @@ tl_object_ptr<telegram_api::InputPrivacyRule> PrivacyManager::UserPrivacySetting
Result<PrivacyManager::UserPrivacySettingRule> PrivacyManager::UserPrivacySettingRule::from_telegram_api(
tl_object_ptr<telegram_api::PrivacyRule> rule) {
CHECK(rule != nullptr);
UserPrivacySettingRule res(*rule);
for (auto user_id : res.user_ids_) {
if (!G()->td().get_actor_unsafe()->contacts_manager_->have_user(UserId(user_id))) {
UserPrivacySettingRule result(*rule);
auto td = G()->td().get_actor_unsafe();
for (auto user_id : result.user_ids_) {
if (!td->contacts_manager_->have_user(UserId(user_id))) {
return Status::Error(500, "Got inaccessible user from the server");
}
}
return res;
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, "Got inaccessible chat from the server");
}
}
td->messages_manager_->force_create_dialog(dialog_id, "UserPrivacySettingRule");
}
return result;
}
vector<tl_object_ptr<telegram_api::InputUser>> PrivacyManager::UserPrivacySettingRule::user_ids_as_telegram_api()
const {
vector<tl_object_ptr<telegram_api::InputUser>> res;
vector<tl_object_ptr<telegram_api::InputUser>> result;
for (auto user_id : user_ids_) {
auto input_user = G()->td().get_actor_unsafe()->contacts_manager_->get_input_user(UserId(user_id));
if (input_user != nullptr) {
res.push_back(std::move(input_user));
result.push_back(std::move(input_user));
} else {
LOG(ERROR) << "Have no access to " << user_id;
}
}
return res;
return result;
}
vector<int32> PrivacyManager::UserPrivacySettingRule::user_ids_as_td_api() const {
return user_ids_;
vector<int64> PrivacyManager::UserPrivacySettingRule::chat_ids_as_dialog_ids() const {
vector<int64> 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(dialog_id.get());
}
return result;
}
Result<PrivacyManager::UserPrivacySettingRules> PrivacyManager::UserPrivacySettingRules::from_telegram_api(
@ -260,12 +343,12 @@ Result<PrivacyManager::UserPrivacySettingRules> PrivacyManager::UserPrivacySetti
Result<PrivacyManager::UserPrivacySettingRules> PrivacyManager::UserPrivacySettingRules::from_telegram_api(
vector<tl_object_ptr<telegram_api::PrivacyRule>> rules) {
UserPrivacySettingRules res;
UserPrivacySettingRules result;
for (auto &rule : rules) {
TRY_RESULT(new_rule, UserPrivacySettingRule::from_telegram_api(std::move(rule)));
res.rules_.push_back(new_rule);
result.rules_.push_back(new_rule);
}
return res;
return result;
}
Result<PrivacyManager::UserPrivacySettingRules> PrivacyManager::UserPrivacySettingRules::from_td_api(
@ -273,14 +356,14 @@ Result<PrivacyManager::UserPrivacySettingRules> PrivacyManager::UserPrivacySetti
if (!rules) {
return Status::Error(5, "UserPrivacySettingRules should not be empty");
}
UserPrivacySettingRules res;
UserPrivacySettingRules result;
for (auto &rule : rules->rules_) {
if (!rule) {
return Status::Error(5, "UserPrivacySettingRule should not be empty");
}
res.rules_.emplace_back(*rule);
result.rules_.emplace_back(*rule);
}
return res;
return result;
}
tl_object_ptr<td_api::userPrivacySettingRules> PrivacyManager::UserPrivacySettingRules::as_td_api() const {
@ -316,6 +399,7 @@ void PrivacyManager::get_privacy(tl_object_ptr<td_api::UserPrivacySetting> key,
on_get_result(user_privacy_setting, [&]() -> Result<UserPrivacySettingRules> {
TRY_RESULT(net_query, std::move(x_net_query));
TRY_RESULT(rules, fetch_result<telegram_api::account_getPrivacy>(std::move(net_query)));
LOG(INFO) << "Receive " << to_string(rules);
return UserPrivacySettingRules::from_telegram_api(std::move(rules));
}());
}));
@ -350,6 +434,7 @@ void PrivacyManager::set_privacy(tl_object_ptr<td_api::UserPrivacySetting> key,
promise.set_result([&]() -> Result<Unit> {
TRY_RESULT(net_query, std::move(x_net_query));
TRY_RESULT(rules, fetch_result<telegram_api::account_setPrivacy>(std::move(net_query)));
LOG(INFO) << "Receive " << to_string(rules);
TRY_RESULT(privacy_rules, UserPrivacySettingRules::from_telegram_api(std::move(rules)));
get_info(user_privacy_setting).has_set_query = false;
do_update_privacy(user_privacy_setting, std::move(privacy_rules), true);

View File

@ -6,14 +6,13 @@
//
#pragma once
#include "td/telegram/net/NetQuery.h"
#include "td/telegram/td_api.h"
#include "td/telegram/telegram_api.h"
#include "td/actor/actor.h"
#include "td/actor/PromiseFuture.h"
#include "td/telegram/net/NetQuery.h"
#include "td/utils/common.h"
#include "td/utils/Container.h"
#include "td/utils/Status.h"
@ -73,7 +72,7 @@ class PrivacyManager : public NetQueryCallback {
tl_object_ptr<telegram_api::InputPrivacyRule> as_telegram_api() const;
bool operator==(const UserPrivacySettingRule &other) const {
return type_ == other.type_ && user_ids_ == other.user_ids_;
return type_ == other.type_ && user_ids_ == other.user_ids_ && chat_ids_ == other.chat_ids_;
}
private:
@ -81,17 +80,22 @@ class PrivacyManager : public NetQueryCallback {
AllowContacts,
AllowAll,
AllowUsers,
AllowChatParticipants,
RestrictContacts,
RestrictAll,
RestrictUsers
RestrictUsers,
RestrictChatParticipants
} type_ = Type::RestrictAll;
vector<int32> user_ids_;
vector<int32> user_ids_as_td_api() const;
vector<int32> chat_ids_;
vector<tl_object_ptr<telegram_api::InputUser>> user_ids_as_telegram_api() const;
void set_chat_ids(const vector<int64> &dialog_ids);
vector<int64> chat_ids_as_dialog_ids() const;
explicit UserPrivacySettingRule(const telegram_api::PrivacyRule &rule);
};

View File

@ -8,7 +8,7 @@
namespace td {
constexpr int32 MTPROTO_LAYER = 99;
constexpr int32 MTPROTO_LAYER = 100;
enum class Version : int32 {
Initial,

View File

@ -944,6 +944,9 @@ class CliClient final : public Actor {
if (setting == "photo") {
return td_api::make_object<td_api::userPrivacySettingShowProfilePhoto>();
}
if (setting == "phone_number") {
return td_api::make_object<td_api::userPrivacySettingShowPhoneNumber>();
}
return nullptr;
}
@ -1044,6 +1047,8 @@ class CliClient final : public Actor {
return td_api::make_object<td_api::topChatCategoryInlineBots>();
} else if (category == "call") {
return td_api::make_object<td_api::topChatCategoryCalls>();
} else if (category == "forward") {
return td_api::make_object<td_api::topChatCategoryForwardChats>();
} else {
return td_api::make_object<td_api::topChatCategoryUsers>();
}
@ -1557,11 +1562,17 @@ class CliClient final : public Actor {
} else if (op == "spr") {
string setting;
string allow;
std::tie(setting, allow) = split(args);
string ids;
std::tie(setting, args) = split(args);
std::tie(allow, ids) = split(args);
std::vector<tl_object_ptr<td_api::UserPrivacySettingRule>> rules;
if (allow == "c" || allow == "contacts") {
rules.push_back(td_api::make_object<td_api::userPrivacySettingRuleAllowContacts>());
} else if (allow == "users") {
rules.push_back(td_api::make_object<td_api::userPrivacySettingRuleAllowUsers>(as_user_ids(ids)));
} else if (allow == "chats") {
rules.push_back(td_api::make_object<td_api::userPrivacySettingRuleAllowChatMembers>(as_chat_ids(ids)));
} else if (as_bool(allow)) {
rules.push_back(td_api::make_object<td_api::userPrivacySettingRuleAllowAll>());
} else {