Support new rights in chats.

GitOrigin-RevId: 0cfc8de697a1eed2a323907c36b36b6b634e42b6
This commit is contained in:
levlam 2019-03-19 18:13:16 +03:00
parent 6c5010a807
commit e6d968963b
4 changed files with 334 additions and 137 deletions

View File

@ -2525,15 +2525,17 @@ template <class StorerT>
void ContactsManager::Chat::store(StorerT &storer) const {
using td::store;
bool has_photo = photo.small_file_id.is_valid();
bool use_new_rights = true;
BEGIN_STORE_FLAGS();
STORE_FLAG(left);
STORE_FLAG(kicked);
STORE_FLAG(is_creator);
STORE_FLAG(is_administrator);
STORE_FLAG(everyone_is_administrator);
STORE_FLAG(can_edit);
STORE_FLAG(false);
STORE_FLAG(false);
STORE_FLAG(false);
STORE_FLAG(false);
STORE_FLAG(false);
STORE_FLAG(false);
STORE_FLAG(is_active);
STORE_FLAG(has_photo);
STORE_FLAG(use_new_rights);
END_STORE_FLAGS();
store(title, storer);
@ -2544,12 +2546,21 @@ void ContactsManager::Chat::store(StorerT &storer) const {
store(date, storer);
store(migrated_to_channel_id, storer);
store(version, storer);
store(status, storer);
store(default_restricted_rights, storer);
}
template <class ParserT>
void ContactsManager::Chat::parse(ParserT &parser) {
using td::parse;
bool has_photo;
bool left;
bool kicked;
bool is_creator;
bool is_administrator;
bool everyone_is_administrator;
bool can_edit;
bool use_new_rights;
BEGIN_PARSE_FLAGS();
PARSE_FLAG(left);
PARSE_FLAG(kicked);
@ -2559,6 +2570,7 @@ void ContactsManager::Chat::parse(ParserT &parser) {
PARSE_FLAG(can_edit);
PARSE_FLAG(is_active);
PARSE_FLAG(has_photo);
PARSE_FLAG(use_new_rights);
END_PARSE_FLAGS();
parse(title, parser);
@ -2569,6 +2581,27 @@ void ContactsManager::Chat::parse(ParserT &parser) {
parse(date, parser);
parse(migrated_to_channel_id, parser);
parse(version, parser);
if (use_new_rights) {
parse(status, parser);
parse(default_restricted_rights, parser);
} else {
if (kicked || !is_active) {
status = DialogParticipantStatus::Banned(0);
} else if (left) {
status = DialogParticipantStatus::Left();
} else if (is_creator) {
status = DialogParticipantStatus::Creator(true);
} else if (is_administrator && !everyone_is_administrator) {
status = DialogParticipantStatus::GroupAdministrator(false);
} else {
status = DialogParticipantStatus::Member();
}
if (everyone_is_administrator) {
default_restricted_rights = RestrictedRights(true, true, true, true, true, true, true, true, true, true, true);
} else {
default_restricted_rights = RestrictedRights(true, true, true, true, true, true, true, true, false, false, false);
}
}
}
template <class StorerT>
@ -2813,7 +2846,7 @@ bool ContactsManager::have_input_peer_chat(const Chat *chat, AccessRights access
if (access_rights == AccessRights::Read) {
return true;
}
if (chat->left) {
if (chat->status.is_left()) {
return false;
}
if (access_rights == AccessRights::Write && !chat->is_active) {
@ -4161,7 +4194,7 @@ void ContactsManager::add_chat_participant(ChatId chat_id, UserId user_id, int32
if (!get_chat_status(c).can_invite_users()) {
return promise.set_error(Status::Error(3, "Not enough rights to invite members to the group chat"));
}
} else if (c->kicked) {
} else if (c->status.is_banned()) {
return promise.set_error(Status::Error(3, "User was kicked from the chat"));
}
// TODO upper bound on forward_limit
@ -4396,10 +4429,6 @@ void ContactsManager::change_chat_participant_status(ChatId chat_id, UserId user
return promise.set_error(Status::Error(3, "Need creator rights in the group chat"));
}
if (c->everyone_is_administrator) {
return promise.set_error(Status::Error(3, "Administrators editing is disabled in the group chat"));
}
if (user_id == get_my_id()) {
return promise.set_error(Status::Error(3, "Can't change chat member status of self"));
}
@ -4498,7 +4527,7 @@ void ContactsManager::delete_chat_participant(ChatId chat_id, UserId user_id, Pr
return promise.set_error(Status::Error(3, "Chat is deactivated"));
}
auto my_id = get_my_id();
if (c->left) {
if (c->status.is_left()) {
if (user_id == my_id) {
return promise.set_value(Unit());
} else {
@ -4510,6 +4539,8 @@ void ContactsManager::delete_chat_participant(ChatId chat_id, UserId user_id, Pr
if (!my_status.is_creator()) { // creator can delete anyone
auto participant = get_chat_participant(chat_id, user_id);
if (participant != nullptr) { // if have no information about participant, just send request to the server
/*
TODO
if (c->everyone_is_administrator) {
// if all are administrators, only invited by me participants can be deleted
if (participant->inviter_user_id != my_id) {
@ -4526,6 +4557,7 @@ void ContactsManager::delete_chat_participant(ChatId chat_id, UserId user_id, Pr
return promise.set_error(Status::Error(3, "Need to be inviter of a user to kick it from a basic group"));
}
}
*/
}
}
}
@ -4617,7 +4649,7 @@ ChannelId ContactsManager::migrate_chat_to_megagroup(ChatId chat_id, Promise<Uni
return ChannelId();
}
if (!c->is_creator) {
if (!c->status.is_creator()) {
promise.set_error(Status::Error(3, "Need creator rights in the chat"));
return ChannelId();
}
@ -5467,12 +5499,7 @@ void ContactsManager::on_binlog_chat_event(BinlogEvent &&event) {
auto chat_id = log_event.chat_id;
LOG(INFO) << "Add " << chat_id << " from binlog";
Chat *c = add_chat(chat_id);
if (c->left || !c->kicked) {
LOG(ERROR) << "Skip adding already added " << chat_id;
binlog_erase(G()->td_db()->get_binlog(), event.id_);
return; // TODO fix bug in Binlog and remove that fix
}
CHECK(!c->left && c->kicked);
CHECK(c->status.is_banned());
*c = std::move(log_event.c); // chats come from binlog before all other events, so just add them
c->logevent_id = event.id_;
@ -7340,7 +7367,7 @@ void ContactsManager::on_get_chat_participants(tl_object_ptr<telegram_api::ChatP
case telegram_api::chatParticipantAdmin::ID: {
auto participant = move_tl_object_as<telegram_api::chatParticipantAdmin>(participant_ptr);
dialog_participant = {UserId(participant->user_id_), UserId(participant->inviter_id_), participant->date_,
DialogParticipantStatus::GroupAdministrator(c->is_creator)};
DialogParticipantStatus::GroupAdministrator(c->status.is_creator())};
break;
}
default:
@ -8014,7 +8041,7 @@ void ContactsManager::on_update_chat_add_user(ChatId chat_id, UserId inviter_use
repair_chat_participants(chat_id);
return;
}
if (c->left) {
if (c->status.is_left()) {
// possible if updates come out of order
LOG(WARNING) << "Receive updateChatParticipantAdd for left " << chat_id << ". Couldn't apply it";
@ -8075,7 +8102,7 @@ void ContactsManager::on_update_chat_edit_administrator(ChatId chat_id, UserId u
return;
}
if (c->left) {
if (c->status.is_left()) {
// possible if updates come out of order
LOG(WARNING) << "Receive updateChatParticipantAdmin for left " << chat_id << ". Couldn't apply it";
@ -8088,6 +8115,8 @@ void ContactsManager::on_update_chat_edit_administrator(ChatId chat_id, UserId u
}
CHECK(c->version >= 0);
auto status = is_administrator ? DialogParticipantStatus::GroupAdministrator(c->status.is_creator())
: DialogParticipantStatus::Member();
if (version > c->version) {
if (version != c->version + 1) {
LOG(ERROR) << "Administrators of " << chat_id << " with version " << c->version
@ -8098,8 +8127,8 @@ void ContactsManager::on_update_chat_edit_administrator(ChatId chat_id, UserId u
c->version = version;
c->is_changed = true;
if (user_id == get_my_id()) {
on_update_chat_rights(c, chat_id, c->is_creator, is_administrator, c->everyone_is_administrator);
if (user_id == get_my_id() && !c->status.is_creator()) {
on_update_chat_status(c, chat_id, status);
}
update_chat(c, chat_id);
}
@ -8109,8 +8138,7 @@ void ContactsManager::on_update_chat_edit_administrator(ChatId chat_id, UserId u
if (chat_full->version + 1 == version) {
for (auto &participant : chat_full->participants) {
if (participant.user_id == user_id) {
participant.status = is_administrator ? DialogParticipantStatus::GroupAdministrator(c->is_creator)
: DialogParticipantStatus::Member();
participant.status = std::move(status);
chat_full->is_changed = true;
update_chat_full(chat_full, chat_id);
return;
@ -8147,11 +8175,11 @@ void ContactsManager::on_update_chat_delete_user(ChatId chat_id, UserId user_id,
return;
}
if (user_id == get_my_id()) {
LOG_IF(WARNING, !c->left) << "User was removed from " << chat_id
<< " but it is not left the group. Possible if updates comes out of order";
LOG_IF(WARNING, c->status.is_member()) << "User was removed from " << chat_id
<< " but it is not left the group. Possible if updates comes out of order";
return;
}
if (c->left) {
if (c->status.is_left()) {
// possible if updates come out of order
LOG(INFO) << "Receive updateChatParticipantDelete for left " << chat_id;
@ -8178,60 +8206,14 @@ void ContactsManager::on_update_chat_delete_user(ChatId chat_id, UserId user_id,
}
}
void ContactsManager::on_update_chat_everyone_is_administrator(ChatId chat_id, bool everyone_is_administrator,
int32 version) {
if (!chat_id.is_valid()) {
LOG(ERROR) << "Receive invalid " << chat_id;
return;
}
LOG(INFO) << "Receive updateChatAdmins in " << chat_id << " with version " << version
<< " and everyone_is_administrator = " << everyone_is_administrator << ". Current version is " << version;
void ContactsManager::on_update_chat_status(Chat *c, ChatId chat_id, DialogParticipantStatus status) {
if (c->status != status) {
LOG(INFO) << "Update " << chat_id << " status from " << c->status << " to " << status;
bool drop_invite_link = c->status.is_left() != status.is_left();
auto c = get_chat_force(chat_id);
if (c == nullptr) {
LOG(INFO) << "Ignoring update about unknown " << chat_id;
return;
}
c->status = status;
if (c->left) {
// possible if updates come out of order
LOG(WARNING) << "Receive updateChatAdmins for left " << chat_id << ". Couldn't apply it";
repair_chat_participants(chat_id); // just in case
return;
}
if (version <= -1) {
LOG(ERROR) << "Receive wrong version " << version << " for " << chat_id;
return;
}
CHECK(c->version >= 0);
if (version > c->version) {
if (version != c->version + 1) {
LOG(WARNING) << "Anyone can edit of " << chat_id << " with version " << c->version
<< " has changed but new version is " << version;
repair_chat_participants(chat_id);
return;
}
LOG_IF(ERROR, everyone_is_administrator == c->everyone_is_administrator)
<< "Receive updateChatAdmins in " << chat_id << " with version " << version
<< " and everyone_is_administrator = " << everyone_is_administrator
<< ", but everyone_is_administrator is not changed. Current version is " << c->version;
c->version = version;
c->is_changed = true;
on_update_chat_rights(c, chat_id, c->is_creator, c->is_administrator, everyone_is_administrator);
update_chat(c, chat_id);
}
}
void ContactsManager::on_update_chat_left(Chat *c, ChatId chat_id, bool left, bool kicked) {
if (c->left != left || c->kicked != kicked) {
bool drop_invite_link = c->left != left;
c->left = left;
c->kicked = kicked;
if (c->left) {
if (c->status.is_left()) {
c->participant_count = 0;
c->version = -1;
@ -8248,14 +8230,11 @@ void ContactsManager::on_update_chat_left(Chat *c, ChatId chat_id, bool left, bo
}
}
void ContactsManager::on_update_chat_rights(Chat *c, ChatId chat_id, bool is_creator, bool is_administrator,
bool everyone_is_administrator) {
if (c->is_creator != is_creator || c->is_administrator != is_administrator ||
c->everyone_is_administrator != everyone_is_administrator) {
c->is_creator = is_creator;
c->is_administrator = is_administrator;
c->everyone_is_administrator = everyone_is_administrator;
c->can_edit = is_creator || is_administrator || everyone_is_administrator;
void ContactsManager::on_update_chat_default_restricted_rights(Chat *c, ChatId chat_id, RestrictedRights rights) {
if (c->default_restricted_rights != rights) {
LOG(INFO) << "Update " << chat_id << " default restricted rights from " << c->default_restricted_rights << " to "
<< rights;
c->default_restricted_rights = rights;
c->need_send_update = true;
}
}
@ -9031,19 +9010,10 @@ DialogParticipantStatus ContactsManager::get_chat_status(ChatId chat_id) const {
}
DialogParticipantStatus ContactsManager::get_chat_status(const Chat *c) {
if (c->kicked || !c->is_active) {
if (!c->is_active) {
return DialogParticipantStatus::Banned(0);
}
if (c->left) {
return DialogParticipantStatus::Left();
}
if (c->is_creator) {
return DialogParticipantStatus::Creator(true);
}
if (c->can_edit) {
return DialogParticipantStatus::GroupAdministrator(false);
}
return DialogParticipantStatus::Member();
return c->status;
}
bool ContactsManager::is_appointed_chat_administrator(ChatId chat_id) const {
@ -9051,11 +9021,7 @@ bool ContactsManager::is_appointed_chat_administrator(ChatId chat_id) const {
if (c == nullptr) {
return false;
}
if (c->everyone_is_administrator) {
return c->is_creator;
} else {
return c->can_edit;
}
return c->status.is_administrator();
}
FileSourceId ContactsManager::get_chat_photo_file_source_id(ChatId chat_id) {
@ -9756,16 +9722,27 @@ void ContactsManager::on_chat_update(telegram_api::chat &chat, const char *sourc
return;
}
bool has_left = 0 != (chat.flags_ & CHAT_FLAG_USER_HAS_LEFT);
bool was_kicked = 0 != (chat.flags_ & CHAT_FLAG_USER_WAS_KICKED);
if (was_kicked) {
LOG_IF(ERROR, has_left) << "Kicked and left" << debug_str; // only one of the flags can be set
has_left = true;
}
DialogParticipantStatus status = [&]() {
bool is_creator = 0 != (chat.flags_ & CHAT_FLAG_USER_IS_CREATOR);
bool has_left = 0 != (chat.flags_ & CHAT_FLAG_USER_HAS_LEFT);
bool was_kicked = 0 != (chat.flags_ & CHAT_FLAG_USER_WAS_KICKED);
if (was_kicked) {
LOG_IF(ERROR, has_left) << "Kicked and left" << debug_str; // only one of the flags can be set
has_left = true;
}
bool is_creator = 0 != (chat.flags_ & CHAT_FLAG_USER_IS_CREATOR);
bool is_administrator = false; // 0 != (chat.flags_ & CHAT_FLAG_IS_ADMINISTRATOR);
bool everyone_is_administrator = true; // 0 == (chat.flags_ & CHAT_FLAG_ADMINISTRATORS_ENABLED);
if (is_creator) {
return DialogParticipantStatus::Creator(!has_left);
} else if (chat.admin_rights_ != nullptr) {
return get_dialog_participant_status(false, std::move(chat.admin_rights_));
} else if (was_kicked) {
return DialogParticipantStatus::Banned(0);
} else if (has_left) {
return DialogParticipantStatus::Left();
} else {
return DialogParticipantStatus::Member();
}
}();
bool is_active = 0 == (chat.flags_ & CHAT_FLAG_IS_DEACTIVATED);
@ -9806,7 +9783,7 @@ void ContactsManager::on_chat_update(telegram_api::chat &chat, const char *sourc
Chat *c = add_chat(chat_id);
on_update_chat_title(c, chat_id, std::move(chat.title_));
if (!has_left) {
if (!status.is_left()) {
on_update_chat_participant_count(c, chat_id, chat.participants_count_, chat.version_, debug_str);
}
if (c->date != chat.date_) {
@ -9815,8 +9792,8 @@ void ContactsManager::on_chat_update(telegram_api::chat &chat, const char *sourc
c->date = chat.date_;
c->is_changed = true;
}
on_update_chat_left(c, chat_id, has_left, was_kicked);
on_update_chat_rights(c, chat_id, is_creator, is_administrator, everyone_is_administrator);
on_update_chat_status(c, chat_id, std::move(status));
on_update_chat_default_restricted_rights(c, chat_id, get_restricted_rights(std::move(chat.default_banned_rights_)));
on_update_chat_photo(c, chat_id, std::move(chat.photo_));
on_update_chat_active(c, chat_id, is_active);
on_update_chat_migrated_to_channel_id(c, chat_id, migrated_to_channel_id);
@ -9831,18 +9808,16 @@ void ContactsManager::on_chat_update(telegram_api::chatForbidden &chat, const ch
return;
}
bool is_uninited = get_chat_force(chat_id) == nullptr;
Chat *c = add_chat(chat_id);
bool is_uninited = c->left == false && c->kicked == true;
on_update_chat_title(c, chat_id, std::move(chat.title_));
// chat participant count will be updated in on_update_chat_left
// leave rights as is
// chat participant count will be updated in on_update_chat_status
on_update_chat_photo(c, chat_id, nullptr);
if (c->date != 0) {
c->date = 0; // removed in 38-th layer
c->is_changed = true;
}
on_update_chat_left(c, chat_id, true, true);
on_update_chat_status(c, chat_id, DialogParticipantStatus::Banned(0));
if (is_uninited) {
on_update_chat_active(c, chat_id, true);
on_update_chat_migrated_to_channel_id(c, chat_id, ChannelId());
@ -10214,9 +10189,11 @@ tl_object_ptr<td_api::basicGroup> ContactsManager::get_basic_group_object(ChatId
tl_object_ptr<td_api::basicGroup> ContactsManager::get_basic_group_object_const(ChatId chat_id,
const Chat *chat) const {
auto everyone_is_administrator = chat->default_restricted_rights ==
RestrictedRights(true, true, true, true, true, true, true, true, true, true, true);
return make_tl_object<td_api::basicGroup>(
chat_id.get(), chat->participant_count, get_chat_status(chat).get_chat_member_status_object(),
chat->everyone_is_administrator, chat->is_active,
everyone_is_administrator, chat->is_active,
get_supergroup_id_object(chat->migrated_to_channel_id, "get_basic_group_object"));
}

View File

@ -166,7 +166,6 @@ class ContactsManager : public Actor {
void on_update_chat_description(ChatId chat_id, string &&description);
void on_update_chat_edit_administrator(ChatId chat_id, UserId user_id, bool is_administrator, int32 version);
void on_update_chat_delete_user(ChatId chat_id, UserId user_id, int32 version);
void on_update_chat_everyone_is_administrator(ChatId chat_id, bool everyone_is_administrator, int32 version);
void on_update_channel_username(ChannelId channel_id, string &&username);
void on_update_channel_description(ChannelId channel_id, string &&description);
@ -566,13 +565,9 @@ class ContactsManager : public Actor {
int32 version = -1;
ChannelId migrated_to_channel_id;
bool left = false;
bool kicked = true;
bool is_creator = false;
bool is_administrator = false;
bool everyone_is_administrator = true;
bool can_edit = true;
DialogParticipantStatus status = DialogParticipantStatus::Banned(0);
RestrictedRights default_restricted_rights =
RestrictedRights(false, false, false, false, false, false, false, false, false, false, false);
bool is_active = false;
@ -882,12 +877,11 @@ class ContactsManager : public Actor {
tl_object_ptr<telegram_api::botInfo> &&bot_info);
void invalidate_user_full(UserId user_id);
void on_update_chat_left(Chat *c, ChatId chat_id, bool left, bool kicked);
void on_update_chat_status(Chat *c, ChatId chat_id, DialogParticipantStatus status);
void on_update_chat_default_restricted_rights(Chat *c, ChatId chat_id, RestrictedRights rights);
void on_update_chat_participant_count(Chat *c, ChatId chat_id, int32 participant_count, int32 version,
const string &debug_str);
void on_update_chat_photo(Chat *c, ChatId chat_id, tl_object_ptr<telegram_api::ChatPhoto> &&chat_photo_ptr);
void on_update_chat_rights(Chat *c, ChatId chat_id, bool is_creator, bool is_administrator,
bool everyone_is_administrator);
void on_update_chat_title(Chat *c, ChatId chat_id, string &&title);
void on_update_chat_active(Chat *c, ChatId chat_id, bool is_active);
void on_update_chat_migrated_to_channel_id(Chat *c, ChatId chat_id, ChannelId migrated_to_channel_id);

View File

@ -145,7 +145,7 @@ tl_object_ptr<telegram_api::chatAdminRights> DialogParticipantStatus::get_chat_a
flags |= telegram_api::chatAdminRights::ADD_ADMINS_MASK;
}
LOG(INFO) << "Create channel admin rights " << flags;
LOG(INFO) << "Create chat admin rights " << flags;
return make_tl_object<telegram_api::chatAdminRights>(flags, false /*ignored*/, false /*ignored*/, false /*ignored*/,
false /*ignored*/, false /*ignored*/, false /*ignored*/,
false /*ignored*/, false /*ignored*/);
@ -190,7 +190,7 @@ tl_object_ptr<telegram_api::chatBannedRights> DialogParticipantStatus::get_chat_
flags |= telegram_api::chatBannedRights::PIN_MESSAGES_MASK;
}
LOG(INFO) << "Create channel banned rights " << flags << " until " << until_date_;
LOG(INFO) << "Create chat banned rights " << flags << " until " << until_date_;
return make_tl_object<telegram_api::chatBannedRights>(
flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/,
false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/,
@ -397,6 +397,139 @@ DialogParticipantStatus get_dialog_participant_status(
can_change_info_and_settings, can_invite_users, can_pin_messages);
}
RestrictedRights::RestrictedRights(bool can_send_messages, bool can_send_media, bool can_send_stickers,
bool can_send_animations, bool can_send_games, bool can_use_inline_bots,
bool can_add_web_page_previews, bool can_send_polls,
bool can_change_info_and_settings, bool can_invite_users, bool can_pin_messages) {
flags_ = (static_cast<uint32>(can_send_messages) * CAN_SEND_MESSAGES) |
(static_cast<uint32>(can_send_media) * CAN_SEND_MEDIA) |
(static_cast<uint32>(can_send_stickers) * CAN_SEND_STICKERS) |
(static_cast<uint32>(can_send_animations) * CAN_SEND_ANIMATIONS) |
(static_cast<uint32>(can_send_games) * CAN_SEND_GAMES) |
(static_cast<uint32>(can_use_inline_bots) * CAN_USE_INLINE_BOTS) |
(static_cast<uint32>(can_add_web_page_previews) * CAN_ADD_WEB_PAGE_PREVIEWS) |
(static_cast<uint32>(can_send_polls) * CAN_SEND_POLLS) |
(static_cast<uint32>(can_change_info_and_settings) * CAN_CHANGE_INFO_AND_SETTINGS) |
(static_cast<uint32>(can_invite_users) * CAN_INVITE_USERS) |
(static_cast<uint32>(can_pin_messages) * CAN_PIN_MESSAGES);
}
tl_object_ptr<telegram_api::chatBannedRights> RestrictedRights::get_chat_banned_rights() const {
int32 flags = 0;
if (!can_send_messages()) {
flags |= telegram_api::chatBannedRights::SEND_MESSAGES_MASK;
}
if (!can_send_media()) {
flags |= telegram_api::chatBannedRights::SEND_MEDIA_MASK;
}
if (!can_send_stickers()) {
flags |= telegram_api::chatBannedRights::SEND_STICKERS_MASK;
}
if (!can_send_animations()) {
flags |= telegram_api::chatBannedRights::SEND_GIFS_MASK;
}
if (!can_send_games()) {
flags |= telegram_api::chatBannedRights::SEND_GAMES_MASK;
}
if (!can_use_inline_bots()) {
flags |= telegram_api::chatBannedRights::SEND_INLINE_MASK;
}
if (!can_add_web_page_previews()) {
flags |= telegram_api::chatBannedRights::EMBED_LINKS_MASK;
}
if (!can_send_polls()) {
flags |= telegram_api::chatBannedRights::SEND_POLLS_MASK;
}
if (!can_change_info_and_settings()) {
flags |= telegram_api::chatBannedRights::CHANGE_INFO_MASK;
}
if (!can_invite_users()) {
flags |= telegram_api::chatBannedRights::INVITE_USERS_MASK;
}
if (!can_pin_messages()) {
flags |= telegram_api::chatBannedRights::PIN_MESSAGES_MASK;
}
LOG(INFO) << "Create chat banned rights " << flags;
return make_tl_object<telegram_api::chatBannedRights>(flags, false /*ignored*/, false /*ignored*/, false /*ignored*/,
false /*ignored*/, false /*ignored*/, false /*ignored*/,
false /*ignored*/, false /*ignored*/, false /*ignored*/,
false /*ignored*/, false /*ignored*/, false /*ignored*/, 0);
}
bool operator==(const RestrictedRights &lhs, const RestrictedRights &rhs) {
return lhs.flags_ == rhs.flags_;
}
bool operator!=(const RestrictedRights &lhs, const RestrictedRights &rhs) {
return !(lhs == rhs);
}
StringBuilder &operator<<(StringBuilder &string_builder, const RestrictedRights &status) {
string_builder << "Restricted: ";
if (!status.can_send_messages()) {
string_builder << "(text)";
}
if (!status.can_send_media()) {
string_builder << "(media)";
}
if (!status.can_send_stickers()) {
string_builder << "(stickers)";
}
if (!status.can_send_animations()) {
string_builder << "(animations)";
}
if (!status.can_send_games()) {
string_builder << "(games)";
}
if (!status.can_send_polls()) {
string_builder << "(polls)";
}
if (!status.can_use_inline_bots()) {
string_builder << "(inline bots)";
}
if (!status.can_add_web_page_previews()) {
string_builder << "(links)";
}
if (!status.can_change_info_and_settings()) {
string_builder << "(change)";
}
if (!status.can_invite_users()) {
string_builder << "(invite)";
}
if (!status.can_pin_messages()) {
string_builder << "(pin)";
}
return string_builder;
}
RestrictedRights get_restricted_rights(const tl_object_ptr<telegram_api::chatBannedRights> &banned_rights) {
if (banned_rights == nullptr) {
return RestrictedRights(false, false, false, false, false, false, false, false, false, true, false);
}
bool can_view_messages = (banned_rights->flags_ & telegram_api::chatBannedRights::VIEW_MESSAGES_MASK) == 0;
if (!can_view_messages) {
LOG(ERROR) << "Can't view messages in restricted rights " << to_string(banned_rights);
}
LOG_IF(ERROR, banned_rights->until_date_ != std::numeric_limits<int32>::max())
<< "Have until date " << banned_rights->until_date_ << " in restricted rights";
bool can_send_messages = (banned_rights->flags_ & telegram_api::chatBannedRights::SEND_MESSAGES_MASK) == 0;
bool can_send_media_messages = (banned_rights->flags_ & telegram_api::chatBannedRights::SEND_MEDIA_MASK) == 0;
bool can_send_stickers = (banned_rights->flags_ & telegram_api::chatBannedRights::SEND_STICKERS_MASK) == 0;
bool can_send_animations = (banned_rights->flags_ & telegram_api::chatBannedRights::SEND_GIFS_MASK) == 0;
bool can_send_games = (banned_rights->flags_ & telegram_api::chatBannedRights::SEND_GAMES_MASK) == 0;
bool can_use_inline_bots = (banned_rights->flags_ & telegram_api::chatBannedRights::SEND_INLINE_MASK) == 0;
bool can_add_web_page_previews = (banned_rights->flags_ & telegram_api::chatBannedRights::EMBED_LINKS_MASK) == 0;
bool can_send_polls = (banned_rights->flags_ & telegram_api::chatBannedRights::SEND_POLLS_MASK) == 0;
bool can_change_info_and_settings = (banned_rights->flags_ & telegram_api::chatBannedRights::CHANGE_INFO_MASK) == 0;
bool can_invite_users = (banned_rights->flags_ & telegram_api::chatBannedRights::INVITE_USERS_MASK) == 0;
bool can_pin_messages = (banned_rights->flags_ & telegram_api::chatBannedRights::PIN_MESSAGES_MASK) == 0;
return RestrictedRights(can_send_messages, can_send_media_messages, can_send_stickers, can_send_animations,
can_send_games, can_use_inline_bots, can_add_web_page_previews, can_send_polls,
can_change_info_and_settings, can_invite_users, can_pin_messages);
}
StringBuilder &operator<<(StringBuilder &string_builder, const DialogParticipant &dialog_participant) {
return string_builder << '[' << dialog_participant.user_id << " invited by " << dialog_participant.inviter_user_id
<< " at " << dialog_participant.joined_date << " with status " << dialog_participant.status

View File

@ -185,6 +185,10 @@ class DialogParticipantStatus {
return (flags_ & IS_MEMBER) != 0;
}
bool is_left() const {
return (flags_ & IS_MEMBER) == 0;
}
bool is_creator() const {
return type_ == Type::Creator;
}
@ -240,6 +244,93 @@ bool operator!=(const DialogParticipantStatus &lhs, const DialogParticipantStatu
StringBuilder &operator<<(StringBuilder &string_builder, const DialogParticipantStatus &status);
class RestrictedRights {
static constexpr uint32 CAN_SEND_MESSAGES = 1 << 16;
static constexpr uint32 CAN_SEND_MEDIA = 1 << 17;
static constexpr uint32 CAN_SEND_STICKERS = 1 << 18;
static constexpr uint32 CAN_SEND_ANIMATIONS = 1 << 19;
static constexpr uint32 CAN_SEND_GAMES = 1 << 20;
static constexpr uint32 CAN_USE_INLINE_BOTS = 1 << 21;
static constexpr uint32 CAN_ADD_WEB_PAGE_PREVIEWS = 1 << 22;
static constexpr uint32 CAN_SEND_POLLS = 1 << 23;
static constexpr uint32 CAN_CHANGE_INFO_AND_SETTINGS = 1 << 24;
static constexpr uint32 CAN_INVITE_USERS = 1 << 25;
static constexpr uint32 CAN_PIN_MESSAGES = 1 << 26;
uint32 flags_;
public:
RestrictedRights(bool can_send_messages, bool can_send_media, bool can_send_stickers, bool can_send_animations,
bool can_send_games, bool can_use_inline_bots, bool can_add_web_page_previews, bool can_send_polls,
bool can_change_info_and_settings, bool can_invite_users, bool can_pin_messages);
tl_object_ptr<telegram_api::chatBannedRights> get_chat_banned_rights() const;
bool can_change_info_and_settings() const {
return (flags_ & CAN_CHANGE_INFO_AND_SETTINGS) != 0;
}
bool can_invite_users() const {
return (flags_ & CAN_INVITE_USERS);
}
bool can_pin_messages() const {
return (flags_ & CAN_PIN_MESSAGES) != 0;
}
bool can_send_messages() const {
return (flags_ & CAN_SEND_MESSAGES) != 0;
}
bool can_send_media() const {
return (flags_ & CAN_SEND_MEDIA) != 0;
}
bool can_send_stickers() const {
return (flags_ & CAN_SEND_STICKERS) != 0;
}
bool can_send_animations() const {
return (flags_ & CAN_SEND_ANIMATIONS) != 0;
}
bool can_send_games() const {
return (flags_ & CAN_SEND_GAMES) != 0;
}
bool can_use_inline_bots() const {
return (flags_ & CAN_USE_INLINE_BOTS) != 0;
}
bool can_add_web_page_previews() const {
return (flags_ & CAN_ADD_WEB_PAGE_PREVIEWS) != 0;
}
bool can_send_polls() const {
return (flags_ & CAN_SEND_POLLS) != 0;
}
template <class StorerT>
void store(StorerT &storer) const {
td::store(flags_, storer);
}
template <class ParserT>
void parse(ParserT &parser) {
td::parse(flags_, parser);
}
friend bool operator==(const RestrictedRights &lhs, const RestrictedRights &rhs);
friend StringBuilder &operator<<(StringBuilder &string_builder, const RestrictedRights &status);
};
bool operator==(const RestrictedRights &lhs, const RestrictedRights &rhs);
bool operator!=(const RestrictedRights &lhs, const RestrictedRights &rhs);
StringBuilder &operator<<(StringBuilder &string_builder, const RestrictedRights &status);
struct DialogParticipant {
UserId user_id;
UserId inviter_user_id;
@ -309,4 +400,6 @@ DialogParticipantStatus get_dialog_participant_status(bool can_be_edited,
DialogParticipantStatus get_dialog_participant_status(
bool is_member, const tl_object_ptr<telegram_api::chatBannedRights> &banned_rights);
RestrictedRights get_restricted_rights(const tl_object_ptr<telegram_api::chatBannedRights> &banned_rights);
} // namespace td