diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 1ba4b0ced..8bd62477a 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -455,17 +455,18 @@ chatMemberStatusCreator custom_title:string is_anonymous:Bool is_member:Bool = C //@description The user is a member of a chat and has some additional privileges. In basic groups, administrators can edit and delete messages sent by others, add new members, ban unprivileged members, and manage voice chats. In supergroups and channels, there are more detailed options for administrator privileges //@custom_title A custom title of the administrator; 0-16 characters without emojis; applicable to supergroups only //@can_be_edited True, if the current user can edit the administrator privileges for the called user +//@can_manage_chat True, if the administrator can get chat event log, get chat statistics, get message statistics in channels, get channel members, see anonymous administrators in supergoups and ignore slow mode. Implied by any other privilege; applicable to supergroups and channels only //@can_change_info True, if the administrator can change the chat title, photo, and other settings //@can_post_messages True, if the administrator can create channel posts; applicable to channels only //@can_edit_messages True, if the administrator can edit messages of other users and pin messages; applicable to channels only //@can_delete_messages True, if the administrator can delete messages of other users //@can_invite_users True, if the administrator can invite new users to the chat //@can_restrict_members True, if the administrator can restrict, ban, or unban chat members -//@can_pin_messages True, if the administrator can pin messages; applicable to groups only +//@can_pin_messages True, if the administrator can pin messages; applicable to basic groups and supergroups only //@can_promote_members True, if the administrator can add new administrators with a subset of their own privileges or demote administrators that were directly or indirectly promoted by them -//@can_manage_voice_chats True, if the administrator can manage voice chats; applicable to groups only +//@can_manage_voice_chats True, if the administrator can manage voice chats; applicable to basic groups and supergroups only //@is_anonymous True, if the administrator isn't shown in the chat member list and sends messages anonymously; applicable to supergroups only -chatMemberStatusAdministrator custom_title:string can_be_edited:Bool can_change_info:Bool can_post_messages:Bool can_edit_messages:Bool can_delete_messages:Bool can_invite_users:Bool can_restrict_members:Bool can_pin_messages:Bool can_promote_members:Bool can_manage_voice_chats:Bool is_anonymous:Bool = ChatMemberStatus; +chatMemberStatusAdministrator custom_title:string can_be_edited:Bool can_manage_chat:Bool can_change_info:Bool can_post_messages:Bool can_edit_messages:Bool can_delete_messages:Bool can_invite_users:Bool can_restrict_members:Bool can_pin_messages:Bool can_promote_members:Bool can_manage_voice_chats:Bool is_anonymous:Bool = ChatMemberStatus; //@description The user is a member of a chat, without any additional privileges or restrictions chatMemberStatusMember = ChatMemberStatus; diff --git a/td/generate/scheme/td_api.tlo b/td/generate/scheme/td_api.tlo index dd0952f59..3693d28f4 100644 Binary files a/td/generate/scheme/td_api.tlo and b/td/generate/scheme/td_api.tlo differ diff --git a/td/telegram/DialogParticipant.cpp b/td/telegram/DialogParticipant.cpp index a8ef0814c..8ba950082 100644 --- a/td/telegram/DialogParticipant.cpp +++ b/td/telegram/DialogParticipant.cpp @@ -37,12 +37,13 @@ DialogParticipantStatus DialogParticipantStatus::Creator(bool is_member, bool is } DialogParticipantStatus DialogParticipantStatus::Administrator(bool is_anonymous, string rank, bool can_be_edited, - bool can_change_info, bool can_post_messages, - bool can_edit_messages, bool can_delete_messages, - bool can_invite_users, bool can_restrict_members, - bool can_pin_messages, bool can_promote_members, - bool can_manage_calls) { + bool can_manage_dialog, bool can_change_info, + bool can_post_messages, bool can_edit_messages, + bool can_delete_messages, bool can_invite_users, + bool can_restrict_members, bool can_pin_messages, + bool can_promote_members, bool can_manage_calls) { uint32 flags = (static_cast(can_be_edited) * CAN_BE_EDITED) | + (static_cast(can_manage_dialog) * CAN_MANAGE_DIALOG) | (static_cast(can_change_info) * CAN_CHANGE_INFO_AND_SETTINGS_ADMIN) | (static_cast(can_post_messages) * CAN_POST_MESSAGES) | (static_cast(can_edit_messages) * CAN_EDIT_MESSAGES) | @@ -56,6 +57,7 @@ DialogParticipantStatus DialogParticipantStatus::Administrator(bool is_anonymous if (flags == 0 || flags == CAN_BE_EDITED) { return Member(); } + flags |= CAN_MANAGE_DIALOG; return DialogParticipantStatus(Type::Administrator, IS_MEMBER | ALL_RESTRICTED_RIGHTS | flags, 0, std::move(rank)); } @@ -94,14 +96,14 @@ DialogParticipantStatus DialogParticipantStatus::Banned(int32 banned_until_date) } DialogParticipantStatus DialogParticipantStatus::GroupAdministrator(bool is_creator) { - return Administrator(false, string(), is_creator, true, false, false, true, true, true, true, false, true); + return Administrator(false, string(), is_creator, true, true, false, false, true, true, true, true, false, true); } DialogParticipantStatus DialogParticipantStatus::ChannelAdministrator(bool is_creator, bool is_megagroup) { if (is_megagroup) { - return Administrator(false, string(), is_creator, true, false, false, true, true, true, true, false, false); + return Administrator(false, string(), is_creator, true, true, false, false, true, true, true, true, false, false); } else { - return Administrator(false, string(), is_creator, false, true, true, true, false, true, false, false, false); + return Administrator(false, string(), is_creator, true, false, true, true, true, false, true, false, false, false); } } @@ -117,9 +119,9 @@ tl_object_ptr DialogParticipantStatus::get_chat_member return td_api::make_object(rank_, is_anonymous(), is_member()); case Type::Administrator: return td_api::make_object( - rank_, can_be_edited(), can_change_info_and_settings(), can_post_messages(), can_edit_messages(), - can_delete_messages(), can_invite_users(), can_restrict_members(), can_pin_messages(), can_promote_members(), - can_manage_calls(), is_anonymous()); + rank_, can_be_edited(), can_manage_dialog(), can_change_info_and_settings(), can_post_messages(), + can_edit_messages(), can_delete_messages(), can_invite_users(), can_restrict_members(), can_pin_messages(), + can_promote_members(), can_manage_calls(), is_anonymous()); case Type::Member: return td_api::make_object(); case Type::Restricted: @@ -167,6 +169,9 @@ tl_object_ptr DialogParticipantStatus::get_chat_a if (is_anonymous()) { flags |= telegram_api::chatAdminRights::ANONYMOUS_MASK; } + if (can_manage_dialog()) { + flags |= telegram_api::chatAdminRights::OTHER_MASK; + } LOG(INFO) << "Create chat admin rights " << flags; return make_tl_object( @@ -297,6 +302,9 @@ StringBuilder &operator<<(StringBuilder &string_builder, const DialogParticipant return string_builder; case DialogParticipantStatus::Type::Administrator: string_builder << "Administrator: "; + if (status.can_manage_dialog()) { + string_builder << "(manage)"; + } if (status.can_change_info_and_settings()) { string_builder << "(change)"; } @@ -404,7 +412,7 @@ DialogParticipantStatus get_dialog_participant_status(const tl_object_ptr(status.get()); return DialogParticipantStatus::Administrator( - st->is_anonymous_, st->custom_title_, true /*st->can_be_edited_*/, st->can_change_info_, + st->is_anonymous_, st->custom_title_, true /*st->can_be_edited_*/, st->can_manage_chat_, st->can_change_info_, st->can_post_messages_, st->can_edit_messages_, st->can_delete_messages_, st->can_invite_users_, st->can_restrict_members_, st->can_pin_messages_, st->can_promote_members_, st->can_manage_voice_chats_); } @@ -449,10 +457,14 @@ DialogParticipantStatus get_dialog_participant_status(bool can_be_edited, bool can_promote_members = (admin_rights->flags_ & telegram_api::chatAdminRights::ADD_ADMINS_MASK) != 0; bool can_manage_calls = (admin_rights->flags_ & telegram_api::chatAdminRights::MANAGE_CALL_MASK) != 0; bool is_anonymous = (admin_rights->flags_ & telegram_api::chatAdminRights::ANONYMOUS_MASK) != 0; - return DialogParticipantStatus::Administrator(is_anonymous, std::move(rank), can_be_edited, can_change_info, - can_post_messages, can_edit_messages, can_delete_messages, - can_invite_users, can_restrict_members, can_pin_messages, - can_promote_members, can_manage_calls); + bool can_manage_dialog = (admin_rights->flags_ & telegram_api::chatAdminRights::OTHER_MASK) != 0; + if (!can_manage_dialog) { + LOG(ERROR) << "Receive wrong other flag in " << to_string(admin_rights); + } + return DialogParticipantStatus::Administrator(is_anonymous, std::move(rank), can_be_edited, can_manage_dialog, + can_change_info, can_post_messages, can_edit_messages, + can_delete_messages, can_invite_users, can_restrict_members, + can_pin_messages, can_promote_members, can_manage_calls); } DialogParticipantStatus get_dialog_participant_status( diff --git a/td/telegram/DialogParticipant.h b/td/telegram/DialogParticipant.h index b382ba790..9606ab33b 100644 --- a/td/telegram/DialogParticipant.h +++ b/td/telegram/DialogParticipant.h @@ -121,6 +121,7 @@ class DialogParticipantStatus { static constexpr uint32 CAN_PIN_MESSAGES_ADMIN = 1 << 7; static constexpr uint32 CAN_PROMOTE_MEMBERS = 1 << 8; static constexpr uint32 CAN_MANAGE_CALLS = 1 << 9; + static constexpr uint32 CAN_MANAGE_DIALOG = 1 << 10; static constexpr uint32 CAN_BE_EDITED = 1 << 15; @@ -144,9 +145,10 @@ class DialogParticipantStatus { static constexpr int TYPE_SHIFT = 28; static constexpr uint32 HAS_UNTIL_DATE = 1u << 31; - static constexpr uint32 ALL_ADMINISTRATOR_RIGHTS = - CAN_CHANGE_INFO_AND_SETTINGS_ADMIN | CAN_POST_MESSAGES | CAN_EDIT_MESSAGES | CAN_DELETE_MESSAGES | - CAN_INVITE_USERS_ADMIN | CAN_RESTRICT_MEMBERS | CAN_PIN_MESSAGES_ADMIN | CAN_PROMOTE_MEMBERS | CAN_MANAGE_CALLS; + static constexpr uint32 ALL_ADMINISTRATOR_RIGHTS = CAN_CHANGE_INFO_AND_SETTINGS_ADMIN | CAN_POST_MESSAGES | + CAN_EDIT_MESSAGES | CAN_DELETE_MESSAGES | CAN_INVITE_USERS_ADMIN | + CAN_RESTRICT_MEMBERS | CAN_PIN_MESSAGES_ADMIN | + CAN_PROMOTE_MEMBERS | CAN_MANAGE_CALLS | CAN_MANAGE_DIALOG; static constexpr uint32 ALL_ADMIN_PERMISSION_RIGHTS = CAN_CHANGE_INFO_AND_SETTINGS_BANNED | CAN_INVITE_USERS_BANNED | CAN_PIN_MESSAGES_BANNED; @@ -171,9 +173,10 @@ class DialogParticipantStatus { public: static DialogParticipantStatus Creator(bool is_member, bool is_anonymous, string rank); - static DialogParticipantStatus Administrator(bool is_anonymous, string rank, bool can_be_edited, bool can_change_info, - bool can_post_messages, bool can_edit_messages, bool can_delete_messages, - bool can_invite_users, bool can_restrict_members, bool can_pin_messages, + static DialogParticipantStatus Administrator(bool is_anonymous, string rank, bool can_be_edited, + bool can_manage_dialog, bool can_change_info, bool can_post_messages, + bool can_edit_messages, bool can_delete_messages, bool can_invite_users, + bool can_restrict_members, bool can_pin_messages, bool can_promote_members, bool can_manage_calls); static DialogParticipantStatus Member(); @@ -208,6 +211,10 @@ class DialogParticipantStatus { // unrestricts user if restriction time expired. Should be called before all privileges checks void update_restrictions() const; + bool can_manage_dialog() const { + return (flags_ & CAN_MANAGE_DIALOG) != 0; + } + bool can_change_info_and_settings() const { return (flags_ & CAN_CHANGE_INFO_AND_SETTINGS_ADMIN) != 0 || (flags_ & CAN_CHANGE_INFO_AND_SETTINGS_BANNED) != 0; } @@ -359,6 +366,8 @@ class DialogParticipantStatus { if (is_creator()) { flags_ |= ALL_ADMINISTRATOR_RIGHTS | ALL_PERMISSION_RIGHTS; + } else if (is_administrator()) { + flags_ |= CAN_MANAGE_DIALOG; } } diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index e02ba1c69..dde219695 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -3622,30 +3622,30 @@ class CliClient final : public Actor { status = td_api::make_object("", true, true); } else if (status_str == "uncreator") { status = td_api::make_object("", false, false); - } else if (status_str == "anon") { - status = td_api::make_object("anon", true, true, true, true, true, true, - true, true, true, false, true); } else if (status_str == "anonadmin") { - status = td_api::make_object("anon", false, false, false, false, false, - false, false, false, false, false, true); + status = td_api::make_object("anon", true, true, true, true, true, true, + true, true, true, true, true, true); + } else if (status_str == "anon") { + status = td_api::make_object( + "anon", false, false, false, false, false, false, false, false, false, false, false, true); } else if (status_str == "addadmin") { - status = td_api::make_object("anon", false, false, false, false, false, - false, false, false, true, false, false); + status = td_api::make_object( + "anon", false, false, false, false, false, false, false, false, false, true, false, false); } else if (status_str == "calladmin") { - status = td_api::make_object("anon", false, false, false, false, false, - false, false, false, false, true, false); + status = td_api::make_object( + "anon", false, false, false, false, false, false, false, false, false, false, true, false); } else if (status_str == "admin") { - status = td_api::make_object("", true, true, true, true, true, true, - true, true, true, false, false); + status = td_api::make_object("", true, false, true, true, true, true, + true, true, true, true, true, false); } else if (status_str == "adminq") { - status = td_api::make_object("title", true, true, true, true, true, true, - true, true, true, false, false); + status = td_api::make_object("title", true, false, true, true, true, + true, true, true, true, true, true, false); } else if (status_str == "minadmin") { status = td_api::make_object("", true, true, false, false, false, false, - false, false, false, false, false); + false, false, false, false, false, false); } else if (status_str == "unadmin") { status = td_api::make_object("", true, false, false, false, false, false, - false, false, false, false, false); + false, false, false, false, false, false); } else if (status_str == "rest") { status = td_api::make_object( true, static_cast(120 + std::time(nullptr)),