From 454d8d3987392f1cc8c63ec90c66a179450e5e67 Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 20 Mar 2019 15:28:06 +0300 Subject: [PATCH] Add td_api::chatPermissions support. GitOrigin-RevId: 38cc232035e54665e140772b13316c31ecc38df6 --- td/generate/scheme/td_api.tl | 35 +++--- td/generate/scheme/td_api.tlo | Bin 152324 -> 152532 bytes td/telegram/ContactsManager.cpp | 130 ++++++++++++++-------- td/telegram/ContactsManager.h | 17 ++- td/telegram/DialogParticipant.cpp | 35 ++++-- td/telegram/DialogParticipant.h | 178 +++++++++++++++--------------- td/telegram/MessagesManager.cpp | 27 +++++ td/telegram/MessagesManager.h | 3 + td/telegram/cli.cpp | 13 ++- 9 files changed, 271 insertions(+), 167 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 874b3d8f..46be7881 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -317,6 +317,18 @@ userProfilePhotos total_count:int32 photos:vector = UserProfil users total_count:int32 user_ids:vector = Users; +//@description Describes actions permitted to be done by a user in a chat +//@can_send_messages True, if the user can send text messages, contacts, locations, and venues +//@can_send_media_messages True, if the user can send audio files, documents, photos, videos, video notes, and voice notes. Implies can_send_messages permissions +//@can_send_polls True, if the user can send polls. Implies can_send_messages permissions +//@can_send_other_messages True, if the user can send animations, games, and stickers and use inline bots. Implies can_send_media_messages permissions +//@can_add_web_page_previews True, if the user may add a web page preview to his messages. Implies can_send_messages permissions +//@can_change_info True, if the user can change the chat title, photo, and other settings +//@can_invite_users True, if the user can invite new users to the chat +//@can_pin_messages True, if the user can pin messages +chatPermissions can_send_messages:Bool can_send_media_messages:Bool can_send_polls:Bool can_send_other_messages:Bool can_add_web_page_previews:Bool can_change_info:Bool can_invite_users:Bool can_pin_messages:Bool = ChatPermissions; + + //@class ChatMemberStatus @description Provides information about the status of a member in a chat //@description The user is the creator of a chat and has all the administrator privileges @is_member True, if the user is a member of the chat @@ -340,15 +352,8 @@ chatMemberStatusMember = ChatMemberStatus; //@description The user is under certain restrictions in the chat. Not supported in basic groups and channels //@is_member True, if the user is a member of the chat //@restricted_until_date Point in time (Unix timestamp) when restrictions will be lifted from the user; 0 if never. If the user is restricted for more than 366 days or for less than 30 seconds from the current time, the user is considered to be restricted forever -//@can_send_messages True, if the user can send text messages, contacts, locations, and venues -//@can_send_media_messages True, if the user can send audio files, documents, photos, videos, video notes, and voice notes. Implies can_send_messages permissions -//@can_send_polls True, if the user can send polls. Implies can_send_messages permissions -//@can_send_other_messages True, if the user can send animations, games, and stickers and use inline bots. Implies can_send_media_messages permissions -//@can_add_web_page_previews True, if the user may add a web page preview to his messages. Implies can_send_messages permissions -//@can_change_info True, if the user can change the chat title, photo, and other settings; applicable to groups only -//@can_invite_users True, if the user can invite new users to the chat; applicable to groups only -//@can_pin_messages True, if the user can pin messages; applicable to groups only -chatMemberStatusRestricted is_member:Bool restricted_until_date:int32 can_send_messages:Bool can_send_media_messages:Bool can_send_polls:Bool can_send_other_messages:Bool can_add_web_page_previews:Bool can_change_info:Bool can_invite_users:Bool can_pin_messages:Bool = ChatMemberStatus; +//@permissions User permissions in the chat +chatMemberStatusRestricted is_member:Bool restricted_until_date:int32 permissions:chatPermissions = ChatMemberStatus; //@description The user is not a chat member chatMemberStatusLeft = ChatMemberStatus; @@ -412,10 +417,9 @@ supergroupMembersFilterBots = SupergroupMembersFilter; //@id Group identifier //@member_count Number of members in the group //@status Status of the current user in the group -//@everyone_is_administrator True, if all members have been granted administrator rights in the group //@is_active True, if the group is active //@upgraded_to_supergroup_id Identifier of the supergroup to which this group was upgraded; 0 if none -basicGroup id:int32 member_count:int32 status:ChatMemberStatus everyone_is_administrator:Bool is_active:Bool upgraded_to_supergroup_id:int32 = BasicGroup; +basicGroup id:int32 member_count:int32 status:ChatMemberStatus is_active:Bool upgraded_to_supergroup_id:int32 = BasicGroup; //@description Contains full information about a basic group @param_description Group description @creator_user_id User identifier of the creator of the group; 0 if unknown @members Group members @invite_link Invite link for this group; available only for the group creator and only after it has been generated at least once basicGroupFullInfo description:string creator_user_id:int32 members:vector invite_link:string = BasicGroupFullInfo; @@ -427,13 +431,12 @@ basicGroupFullInfo description:string creator_user_id:int32 members:vector = Chats; @@ -2468,6 +2472,9 @@ updateChatTitle chat_id:int53 title:string = Update; //@description A chat photo was changed @chat_id Chat identifier @photo The new chat photo; may be null updateChatPhoto chat_id:int53 photo:chatPhoto = Update; +//@description Chat permissions was changed @chat_id Chat identifier @permissions The new chat permissions +updateChatPermissions chat_id:int53 permissions:chatPermissions = Update; + //@description The last message of a chat was changed. If last_message is null then the last message in the chat became unknown. Some new unknown messages might be added to the chat in this case @chat_id Chat identifier @last_message The new last message in the chat; may be null @order New value of the chat order updateChatLastMessage chat_id:int53 last_message:message order:int64 = Update; diff --git a/td/generate/scheme/td_api.tlo b/td/generate/scheme/td_api.tlo index c245422c8a16c5757ed2a68a1ccbb27d41ec3ce2..6320182bb4bf18ac29a4f2dd739528eadcc743b1 100644 GIT binary patch delta 2757 zcmZ`*ZERCj7~Xq#H@Y!&$i^C(cnwXgp>tQLQe{Gg0dtmc17(yrb#o(jN!iNU!hkV4 zHnuUgQ8;5~#wPR!K@-uG)TH}?T9e9`)zpX)KZt-!jSz3tw79qHDay`Q8~oEHA^W179()bTR-6vHu{_ zN()G*8VX{gYrhmk<{+l5tDDCoW$Gnz@%1Ktkm{uwZfkw(Y;G)5f5X68scpK2?6h)@ z+bL^AEbN@rt7dC3n_2l7Tn4OjeW8VcV?1_d-;Ya+8_)UYwUD8P$|6+GC!aLDX?av$ zz%6IFBV8`D5zU!AHx`+4nK{U5R}BYg+9``qX&q%{&FLuPF}#Kt?C^oejIE~W z5*q}CTK3@4wFd(R_dtZJm^zWCDTlMiWTzf>28qLmNSH3Mzh)tcDg*Z;`a$B9*$k=YwHpon0Z?`royDPSyDGzAdHD?v`@-*M_eW+Ug zh=q747)Jn0ldcdf^lShe9ML}k%tl37MZXQeGA{7!#d2vDiM>$A1tt5iHmZe%jI1>i zrCP5|cwcT9GPTxBQvvi-+XXi6BG?6PPTlK5sTRe)ADXz}?Eb8${m{yJwgWgkTI5+> zNzal|`5;)ik^3MTHLVl4^NDWs&HPYTH)@Q`5|EVIb|tB&R(S}Gcs;CwiAd|jocxl9 zatlMH9(3#M!6fBHLJghjLA|>@Im2zBy*;oht{esjaOjaBDyD-_%X!9L^y=uvHAwX$ zGxTu}@cqAz>Lx9vZHdeIY@+H{sz z8p1rfLs>ln3Uy>Kxcg*IjSJ}a1gdH3B)a#U(#?o>g^@;2!4)31n_w{Y0fD@6)Rp>; zG%*e#uIoIl!zQ5vW|~%kkfC2U(+A^FK_Z`)(z*%IubRjNf=o^5{wFB1GG|o7#72?Y zr_?8lH_H!GeQ-$P7nw)QP`zYv`y`Y+uRS}cI+rd^oxh~sKJ12|%4M}a8g=oqI@pXN znRjH3h#Rkf1YBBk6}mVzrCzL@QWrqsl=T|&8n3B+*8ELgQ*mqlqD@v>f*Nt@8}KaF zo>w$QsH?z`{2wa)kHyz}RG ze&?Kf?t8y}RT%lQu;js~Rd4Ck=i!x-J}^9Y<)^(#32KDGEi336Lv^z^Oa_FqoHr2pO8 zC7ixzt4QvA;NdThts-h8|I>&`%eHg@SI_NKBb;s<*F@abLdKnCEhH~bS0x|0o3KT@ z&2?yFwS}tlEd_56Udyiaw^c=r>7m56m8^m~-@*O9(9WL=FDdS-8 z>eVk5x?5F=x`a*+N8f0S9u0 zL9`<~kQ>g5)&rDLL3`w$o(GGcD*wv@Uu=>&2u;oVbLszN{6798)gn=6>XvRE}V?ND?1In z-UUt`QQ8f5F1fm)nM>o{Iq=3F@Nh%8M?>j>Cax##y6X(vP1w=Yy7WisWF@ggKZWPwie=b59l_J=Tcm&FMj`0ZQo!25v$3Zl)8~B;$ z)O8$@yOMp2xh$m{I(gl#X zzG5^h%@PGDAyXpX&rTHQ+@e8>MB^0UGn#H90cKkKBb3ukG4%7t@Z=1|Fk&L6HZ5hm z2*s}|{|8h)nGIa(y$K0bHz{|BUFmdaQa;*>l=)bOVNz;t5=2nMQN4WJdmG>ty7v}T za=+*;jF6YX#dU@$)LEwFnJakBQ!-UWl2^b+XD}=^KL!5f%FhnJLTYBIU^6Mdb?gfZ6y6i6xW!o^EIgm5 m{GHJ0F?cD}yj}<|GvVj%>Cai}$u?n@|5#=5FuH{6`hNjDVD3Qx diff --git a/td/telegram/ContactsManager.cpp b/td/telegram/ContactsManager.cpp index a1c9599b..ba4393b4 100644 --- a/td/telegram/ContactsManager.cpp +++ b/td/telegram/ContactsManager.cpp @@ -2547,7 +2547,7 @@ void ContactsManager::Chat::store(StorerT &storer) const { store(migrated_to_channel_id, storer); store(version, storer); store(status, storer); - store(default_restricted_rights, storer); + store(default_permissions, storer); } template @@ -2583,7 +2583,7 @@ void ContactsManager::Chat::parse(ParserT &parser) { parse(version, parser); if (use_new_rights) { parse(status, parser); - parse(default_restricted_rights, parser); + parse(default_permissions, parser); } else { if (kicked || !is_active) { status = DialogParticipantStatus::Banned(0); @@ -2596,9 +2596,8 @@ void ContactsManager::Chat::parse(ParserT &parser) { } else { status = DialogParticipantStatus::Member(); } - default_restricted_rights = - RestrictedRights(true, true, true, true, true, true, true, true, everyone_is_administrator, - everyone_is_administrator, everyone_is_administrator); + default_permissions = RestrictedRights(true, true, true, true, true, true, true, true, everyone_is_administrator, + everyone_is_administrator, everyone_is_administrator); } } @@ -2609,7 +2608,7 @@ void ContactsManager::Channel::store(StorerT &storer) const { bool has_username = !username.empty(); bool is_restricted = !restriction_reason.empty(); bool use_new_rights = true; - bool have_default_restricted_rights = true; + bool have_default_permissions = true; bool have_participant_count = participant_count != 0; BEGIN_STORE_FLAGS(); STORE_FLAG(false); @@ -2626,7 +2625,7 @@ void ContactsManager::Channel::store(StorerT &storer) const { STORE_FLAG(is_restricted); STORE_FLAG(use_new_rights); STORE_FLAG(have_participant_count); - STORE_FLAG(have_default_restricted_rights); + STORE_FLAG(have_default_permissions); END_STORE_FLAGS(); store(status, storer); @@ -2646,7 +2645,7 @@ void ContactsManager::Channel::store(StorerT &storer) const { store(participant_count, storer); } if (is_megagroup) { - store(default_restricted_rights, storer); + store(default_permissions, storer); } } @@ -2664,7 +2663,7 @@ void ContactsManager::Channel::parse(ParserT &parser) { bool anyone_can_invite; bool use_new_rights; bool have_participant_count; - bool have_default_restricted_rights; + bool have_default_permissions; BEGIN_PARSE_FLAGS(); PARSE_FLAG(left); PARSE_FLAG(kicked); @@ -2680,7 +2679,7 @@ void ContactsManager::Channel::parse(ParserT &parser) { PARSE_FLAG(is_restricted); PARSE_FLAG(use_new_rights); PARSE_FLAG(have_participant_count); - PARSE_FLAG(have_default_restricted_rights); + PARSE_FLAG(have_default_permissions); END_PARSE_FLAGS(); if (use_new_rights) { @@ -2714,10 +2713,10 @@ void ContactsManager::Channel::parse(ParserT &parser) { parse(participant_count, parser); } if (is_megagroup) { - if (have_default_restricted_rights) { - parse(default_restricted_rights, parser); + if (have_default_permissions) { + parse(default_permissions, parser); } else { - default_restricted_rights = + default_permissions = RestrictedRights(true, true, true, true, true, true, true, true, false, anyone_can_invite, false); } } @@ -3014,6 +3013,40 @@ string ContactsManager::get_secret_chat_title(SecretChatId secret_chat_id) const return get_user_title(c->user_id); } +RestrictedRights ContactsManager::get_user_default_permissions(UserId user_id) const { + auto u = get_user(user_id); + if (u == nullptr) { + return RestrictedRights(false, false, false, false, false, false, false, false, false, false, false); + } + + bool can_pin_messages = user_id == get_my_id(); /* TODO */ + return RestrictedRights(true, true, true, true, true, true, true, true, false, false, can_pin_messages); +} + +RestrictedRights ContactsManager::get_chat_default_permissions(ChatId chat_id) const { + auto c = get_chat(chat_id); + if (c == nullptr) { + return RestrictedRights(false, false, false, false, false, false, false, false, false, false, false); + } + return c->default_permissions; +} + +RestrictedRights ContactsManager::get_channel_default_permissions(ChannelId channel_id) const { + auto c = get_channel(channel_id); + if (c == nullptr) { + return RestrictedRights(false, false, false, false, false, false, false, false, false, false, false); + } + return c->default_permissions; +} + +RestrictedRights ContactsManager::get_secret_chat_default_permissions(SecretChatId secret_chat_id) const { + auto c = get_secret_chat(secret_chat_id); + if (c == nullptr) { + return RestrictedRights(false, false, false, false, false, false, false, false, false, false, false); + } + return RestrictedRights(true, true, true, true, true, true, true, true, false, false, false); +} + int32 ContactsManager::get_secret_chat_date(SecretChatId secret_chat_id) const { auto c = get_secret_chat(secret_chat_id); if (c == nullptr) { @@ -6252,8 +6285,12 @@ void ContactsManager::update_chat(Chat *c, ChatId chat_id, bool from_binlog, boo if (c->is_title_changed) { td_->messages_manager_->on_dialog_title_updated(DialogId(chat_id)); } + if (c->is_default_permissions_changed) { + td_->messages_manager_->on_dialog_permissions_updated(DialogId(chat_id)); + } c->is_photo_changed = false; c->is_title_changed = false; + c->is_default_permissions_changed = false; LOG(DEBUG) << "Update " << chat_id << ": is_changed = " << c->is_changed << ", need_send_update = " << c->need_send_update; @@ -6319,8 +6356,12 @@ void ContactsManager::update_channel(Channel *c, ChannelId channel_id, bool from } } } + if (c->is_default_permissions_changed) { + td_->messages_manager_->on_dialog_permissions_updated(DialogId(channel_id)); + } c->is_photo_changed = false; c->is_title_changed = false; + c->is_default_permissions_changed = false; c->is_status_changed = false; c->is_username_changed = false; @@ -8246,12 +8287,14 @@ void ContactsManager::on_update_chat_status(Chat *c, ChatId chat_id, DialogParti } } -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; +void ContactsManager::on_update_chat_default_permissions(Chat *c, ChatId chat_id, + RestrictedRights default_permissions) { + if (c->default_permissions != default_permissions) { + LOG(INFO) << "Update " << chat_id << " default permissions from " << c->default_permissions << " to " + << default_permissions; + c->default_permissions = default_permissions; + c->is_default_permissions_changed = true; + c->is_changed = true; } } @@ -8451,13 +8494,14 @@ void ContactsManager::on_update_channel_status(Channel *c, ChannelId channel_id, } } -void ContactsManager::on_update_channel_default_restricted_rights(Channel *c, ChannelId channel_id, - RestrictedRights rights) { - if (c->default_restricted_rights != rights) { - LOG(INFO) << "Update " << channel_id << " default restricted rights from " << c->default_restricted_rights << " to " - << rights; - c->default_restricted_rights = rights; - c->need_send_update = true; +void ContactsManager::on_update_channel_default_permissions(Channel *c, ChannelId channel_id, + RestrictedRights default_permissions) { + if (c->default_permissions != default_permissions) { + LOG(INFO) << "Update " << channel_id << " default permissions from " << c->default_permissions << " to " + << default_permissions; + c->default_permissions = default_permissions; + c->is_default_permissions_changed = true; + c->is_changed = true; } } @@ -9819,7 +9863,7 @@ void ContactsManager::on_chat_update(telegram_api::chat &chat, const char *sourc c->is_changed = true; } 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_default_permissions(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); @@ -9918,8 +9962,8 @@ void ContactsManager::on_chat_update(telegram_api::channel &channel, const char on_update_channel_title(c, channel_id, std::move(channel.title_)); on_update_channel_username(c, channel_id, std::move(channel.username_)); on_update_channel_photo(c, channel_id, std::move(channel.photo_)); - on_update_channel_default_restricted_rights(c, channel_id, - get_restricted_rights(std::move(channel.default_banned_rights_))); + on_update_channel_default_permissions(c, channel_id, + get_restricted_rights(std::move(channel.default_banned_rights_))); if (c->is_megagroup != is_megagroup || c->is_verified != is_verified) { c->is_megagroup = is_megagroup; @@ -9956,8 +10000,8 @@ void ContactsManager::on_chat_update(telegram_api::channel &channel, const char on_update_channel_photo(c, channel_id, std::move(channel.photo_)); on_update_channel_status(c, channel_id, std::move(status)); on_update_channel_username(c, channel_id, std::move(channel.username_)); // uses status, must be called after - on_update_channel_default_restricted_rights(c, channel_id, - get_restricted_rights(std::move(channel.default_banned_rights_))); + on_update_channel_default_permissions(c, channel_id, + get_restricted_rights(std::move(channel.default_banned_rights_))); if (participant_count != 0 && participant_count != c->participant_count) { c->participant_count = participant_count; @@ -10012,7 +10056,7 @@ void ContactsManager::on_chat_update(telegram_api::channelForbidden &channel, co int32 unban_date = (channel.flags_ & CHANNEL_FLAG_HAS_UNBAN_DATE) != 0 ? channel.until_date_ : 0; on_update_channel_status(c, channel_id, DialogParticipantStatus::Banned(unban_date)); on_update_channel_username(c, channel_id, ""); // don't know if channel username is empty, but update it anyway - on_update_channel_default_restricted_rights(c, channel_id, get_restricted_rights(nullptr)); + on_update_channel_default_permissions(c, channel_id, get_restricted_rights(nullptr)); bool sign_messages = false; bool is_megagroup = (channel.flags_ & CHANNEL_FLAG_IS_MEGAGROUP) != 0; @@ -10185,10 +10229,9 @@ int32 ContactsManager::get_basic_group_id_object(ChatId chat_id, const char *sou if (chat_id.is_valid() && get_chat(chat_id) == nullptr && unknown_chats_.count(chat_id) == 0) { LOG(ERROR) << "Have no info about " << chat_id << " from " << source; unknown_chats_.insert(chat_id); - send_closure( - G()->td(), &Td::send_update, - td_api::make_object(td_api::make_object( - chat_id.get(), 0, DialogParticipantStatus::Banned(0).get_chat_member_status_object(), true, true, 0))); + send_closure(G()->td(), &Td::send_update, + td_api::make_object(td_api::make_object( + chat_id.get(), 0, DialogParticipantStatus::Banned(0).get_chat_member_status_object(), true, 0))); } return chat_id.get(); } @@ -10209,11 +10252,8 @@ tl_object_ptr ContactsManager::get_basic_group_object(ChatId tl_object_ptr 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( - chat_id.get(), chat->participant_count, get_chat_status(chat).get_chat_member_status_object(), - everyone_is_administrator, chat->is_active, + chat_id.get(), chat->participant_count, get_chat_status(chat).get_chat_member_status_object(), chat->is_active, get_supergroup_id_object(chat->migrated_to_channel_id, "get_basic_group_object")); } @@ -10238,7 +10278,7 @@ int32 ContactsManager::get_supergroup_id_object(ChannelId channel_id, const char send_closure(G()->td(), &Td::send_update, td_api::make_object(td_api::make_object( channel_id.get(), string(), 0, DialogParticipantStatus::Banned(0).get_chat_member_status_object(), - 0, false, false, true, false, ""))); + 0, false, true, false, ""))); } return channel_id.get(); } @@ -10252,10 +10292,10 @@ tl_object_ptr ContactsManager::get_supergroup_object(Channel if (channel == nullptr) { return nullptr; } - return make_tl_object( - channel_id.get(), channel->username, channel->date, get_channel_status(channel).get_chat_member_status_object(), - channel->participant_count, channel->default_restricted_rights.can_invite_users(), channel->sign_messages, - !channel->is_megagroup, channel->is_verified, channel->restriction_reason); + return make_tl_object(channel_id.get(), channel->username, channel->date, + get_channel_status(channel).get_chat_member_status_object(), + channel->participant_count, channel->sign_messages, !channel->is_megagroup, + channel->is_verified, channel->restriction_reason); } tl_object_ptr ContactsManager::get_supergroup_full_info_object(ChannelId channel_id) const { diff --git a/td/telegram/ContactsManager.h b/td/telegram/ContactsManager.h index 6ba5c74b..7c8ede2e 100644 --- a/td/telegram/ContactsManager.h +++ b/td/telegram/ContactsManager.h @@ -98,6 +98,11 @@ class ContactsManager : public Actor { string get_channel_title(ChannelId channel_id) const; string get_secret_chat_title(SecretChatId secret_chat_id) const; + RestrictedRights get_user_default_permissions(UserId user_id) const; + RestrictedRights get_chat_default_permissions(ChatId chat_id) const; + RestrictedRights get_channel_default_permissions(ChannelId channel_id) const; + RestrictedRights get_secret_chat_default_permissions(SecretChatId secret_chat_id) const; + bool is_update_about_username_change_received(UserId user_id) const; string get_user_username(UserId user_id) const; @@ -566,13 +571,13 @@ class ContactsManager : public Actor { ChannelId migrated_to_channel_id; DialogParticipantStatus status = DialogParticipantStatus::Banned(0); - RestrictedRights default_restricted_rights{false, false, false, false, false, false, - false, false, false, false, false}; + RestrictedRights default_permissions{false, false, false, false, false, false, false, false, false, false, false}; bool is_active = false; bool is_title_changed = true; bool is_photo_changed = true; + bool is_default_permissions_changed = true; bool is_changed = true; // have new changes not sent to the database except changes visible to the client bool need_send_update = true; // have new changes not sent to the client @@ -607,8 +612,7 @@ class ContactsManager : public Actor { string username; string restriction_reason; DialogParticipantStatus status = DialogParticipantStatus::Banned(0); - RestrictedRights default_restricted_rights{false, false, false, false, false, false, - false, false, false, false, false}; + RestrictedRights default_permissions{false, false, false, false, false, false, false, false, false, false, false}; int32 date = 0; int32 participant_count = 0; @@ -620,6 +624,7 @@ class ContactsManager : public Actor { bool is_title_changed = true; bool is_username_changed = true; bool is_photo_changed = true; + bool is_default_permissions_changed = true; bool is_status_changed = true; bool had_read_access = true; bool was_member = false; @@ -879,7 +884,7 @@ class ContactsManager : public Actor { void invalidate_user_full(UserId user_id); 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_default_permissions(Chat *c, ChatId chat_id, RestrictedRights default_permissions); 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 &&chat_photo_ptr); @@ -898,7 +903,7 @@ class ContactsManager : public Actor { void on_update_channel_title(Channel *c, ChannelId channel_id, string &&title); void on_update_channel_username(Channel *c, ChannelId channel_id, string &&username); void on_update_channel_status(Channel *c, ChannelId channel_id, DialogParticipantStatus &&status); - void on_update_channel_default_restricted_rights(Channel *c, ChannelId channel_id, RestrictedRights rights); + void on_update_channel_default_permissions(Channel *c, ChannelId channel_id, RestrictedRights default_permissions); void on_update_channel_full_invite_link(ChannelFull *channel_full, tl_object_ptr &&invite_link_ptr); diff --git a/td/telegram/DialogParticipant.cpp b/td/telegram/DialogParticipant.cpp index 5cb89a9d..4f9d587c 100644 --- a/td/telegram/DialogParticipant.cpp +++ b/td/telegram/DialogParticipant.cpp @@ -93,6 +93,12 @@ DialogParticipantStatus DialogParticipantStatus::ChannelAdministrator(bool is_cr } } +RestrictedRights DialogParticipantStatus::get_restricted_rights() const { + return RestrictedRights(can_send_messages(), can_send_media(), 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()); +} + tl_object_ptr DialogParticipantStatus::get_chat_member_status_object() const { switch (type_) { case Type::Creator: @@ -104,10 +110,8 @@ tl_object_ptr DialogParticipantStatus::get_chat_member case Type::Member: return make_tl_object(); case Type::Restricted: - return make_tl_object( - is_member(), until_date_, can_send_messages(), can_send_media(), can_send_polls(), - can_send_stickers() && can_send_animations() && can_send_games() && can_use_inline_bots(), - can_add_web_page_previews(), can_change_info_and_settings(), can_invite_users(), can_pin_messages()); + return make_tl_object(is_member(), until_date_, + get_restricted_rights().get_chat_permissions_object()); case Type::Left: return make_tl_object(); case Type::Banned: @@ -339,13 +343,17 @@ DialogParticipantStatus get_dialog_participant_status(const tl_object_ptr(status.get()); - bool can_send_media = - st->can_send_media_messages_ || st->can_send_other_messages_ || st->can_add_web_page_previews_; + auto permissions = st->permissions_.get(); + bool can_send_polls = permissions->can_send_polls_; + bool can_send_media = permissions->can_send_media_messages_ || permissions->can_send_other_messages_ || + permissions->can_add_web_page_previews_; + bool can_send_messages = permissions->can_send_messages_ || can_send_media || can_send_polls; return DialogParticipantStatus::Restricted( - st->is_member_, st->restricted_until_date_, st->can_send_messages_ || can_send_media, can_send_media, - st->can_send_other_messages_, st->can_send_other_messages_, st->can_send_other_messages_, - st->can_send_other_messages_, st->can_add_web_page_previews_, st->can_send_polls_, st->can_change_info_, - st->can_invite_users_, st->can_pin_messages_); + st->is_member_, st->restricted_until_date_, can_send_messages, can_send_media, + permissions->can_send_other_messages_, permissions->can_send_other_messages_, + permissions->can_send_other_messages_, permissions->can_send_other_messages_, + permissions->can_add_web_page_previews_, permissions->can_send_polls_, permissions->can_change_info_, + permissions->can_invite_users_, permissions->can_pin_messages_); } case td_api::chatMemberStatusLeft::ID: return DialogParticipantStatus::Left(); @@ -414,6 +422,13 @@ RestrictedRights::RestrictedRights(bool can_send_messages, bool can_send_media, (static_cast(can_pin_messages) * CAN_PIN_MESSAGES); } +tl_object_ptr RestrictedRights::get_chat_permissions_object() const { + return td_api::make_object( + can_send_messages(), can_send_media(), can_send_polls(), + can_send_stickers() && can_send_animations() && can_send_games() && can_use_inline_bots(), + can_add_web_page_previews(), can_change_info_and_settings(), can_invite_users(), can_pin_messages()); +} + tl_object_ptr RestrictedRights::get_chat_banned_rights() const { int32 flags = 0; if (!can_send_messages()) { diff --git a/td/telegram/DialogParticipant.h b/td/telegram/DialogParticipant.h index 6d239fc0..7cc572c3 100644 --- a/td/telegram/DialogParticipant.h +++ b/td/telegram/DialogParticipant.h @@ -17,6 +17,95 @@ namespace td { +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); + + td_api::object_ptr get_chat_permissions_object() const; + + tl_object_ptr 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 + void store(StorerT &storer) const { + td::store(flags_, storer); + } + + template + 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); + class DialogParticipantStatus { static constexpr uint32 CAN_CHANGE_INFO_AND_SETTINGS_ADMIN = 1 << 0; static constexpr uint32 CAN_POST_MESSAGES = 1 << 1; @@ -96,6 +185,8 @@ class DialogParticipantStatus { // legacy rights static DialogParticipantStatus ChannelAdministrator(bool is_creator, bool is_megagroup); + RestrictedRights get_restricted_rights() const; + tl_object_ptr get_chat_member_status_object() const; tl_object_ptr get_chat_admin_rights() const; @@ -244,93 +335,6 @@ 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 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 - void store(StorerT &storer) const { - td::store(flags_, storer); - } - - template - 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; diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index fd689e14..07a32712 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -13387,6 +13387,7 @@ tl_object_ptr MessagesManager::get_chat_object(const Dialog *d) co return make_tl_object( d->dialog_id.get(), get_chat_type_object(d->dialog_id), get_dialog_title(d->dialog_id), get_chat_photo_object(td_->file_manager_.get(), get_dialog_photo(d->dialog_id)), + get_dialog_permissions(d->dialog_id).get_chat_permissions_object(), get_message_object(d->dialog_id, get_message(d, d->last_message_id)), DialogDate(d->order, d->dialog_id) <= last_dialog_date_ ? d->order : 0, d->pinned_order != DEFAULT_ORDER, d->is_marked_as_unread, d->order == SPONSORED_DIALOG_ORDER, can_delete_for_self, can_delete_for_all_users, @@ -20699,6 +20700,15 @@ void MessagesManager::on_dialog_title_updated(DialogId dialog_id) { } } +void MessagesManager::on_dialog_permissions_updated(DialogId dialog_id) { + auto d = get_dialog(dialog_id); // called from update_user, must not create the dialog + if (d != nullptr && d->is_update_new_chat_sent) { + send_closure(G()->td(), &Td::send_update, + td_api::make_object( + dialog_id.get(), get_dialog_permissions(dialog_id).get_chat_permissions_object())); + } +} + DialogId MessagesManager::resolve_dialog_username(const string &username) { auto it = resolved_usernames_.find(clean_username(username)); if (it != resolved_usernames_.end()) { @@ -21019,6 +21029,23 @@ string MessagesManager::get_dialog_username(DialogId dialog_id) const { } } +RestrictedRights MessagesManager::get_dialog_permissions(DialogId dialog_id) const { + switch (dialog_id.get_type()) { + case DialogType::User: + return td_->contacts_manager_->get_user_default_permissions(dialog_id.get_user_id()); + case DialogType::Chat: + return td_->contacts_manager_->get_chat_default_permissions(dialog_id.get_chat_id()); + case DialogType::Channel: + return td_->contacts_manager_->get_channel_default_permissions(dialog_id.get_channel_id()); + case DialogType::SecretChat: + return td_->contacts_manager_->get_secret_chat_default_permissions(dialog_id.get_secret_chat_id()); + case DialogType::None: + default: + UNREACHABLE(); + return RestrictedRights(false, false, false, false, false, false, false, false, false, false, false); + } +} + void MessagesManager::send_dialog_action(DialogId dialog_id, const tl_object_ptr &action, Promise &&promise) { if (action == nullptr) { diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index 0eb6318b..8a422bac 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -616,6 +616,7 @@ class MessagesManager : public Actor { void on_dialog_photo_updated(DialogId dialog_id); void on_dialog_title_updated(DialogId dialog_id); void on_dialog_username_updated(DialogId dialog_id, const string &old_username, const string &new_username); + void on_dialog_permissions_updated(DialogId dialog_id); void on_resolved_username(const string &username, DialogId dialog_id); void drop_username(const string &username); @@ -1949,6 +1950,8 @@ class MessagesManager : public Actor { string get_dialog_username(DialogId dialog_id) const; + RestrictedRights get_dialog_permissions(DialogId dialog_id) const; + static int64 get_dialog_order(MessageId message_id, int32 message_date); bool update_dialog_draft_message(Dialog *d, unique_ptr &&draft_message, bool from_update, diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 8ce99e25..a2feba54 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -3232,16 +3232,19 @@ class CliClient final : public Actor { false, false, false); } else if (status_str == "rest") { status = td_api::make_object( - true, static_cast(120 + std::time(nullptr)), false, false, false, false, false, false, false, false); + true, static_cast(120 + std::time(nullptr)), + td_api::make_object(false, false, false, false, false, false, false, false)); } else if (status_str == "restkick") { status = td_api::make_object( - false, static_cast(120 + std::time(nullptr)), true, false, false, false, false, false, false, false); + false, static_cast(120 + std::time(nullptr)), + td_api::make_object(true, false, false, false, false, false, false, false)); } else if (status_str == "restunkick") { status = td_api::make_object( - true, static_cast(120 + std::time(nullptr)), true, false, false, false, false, false, false, false); + true, static_cast(120 + std::time(nullptr)), + td_api::make_object(true, false, false, false, false, false, false, false)); } else if (status_str == "unrest") { - status = td_api::make_object(true, 0, true, true, true, true, true, true, - true, true); + status = td_api::make_object( + true, 0, td_api::make_object(true, true, true, true, true, true, true, true)); } if (status != nullptr) { send_request(td_api::make_object(as_chat_id(chat_id), as_user_id(user_id),