Always adjust administrator rights for supergroups and channels.

This commit is contained in:
levlam 2022-04-04 16:19:41 +03:00
parent 99b79911e0
commit c3996b4726
7 changed files with 97 additions and 65 deletions

View File

@ -6962,11 +6962,13 @@ void ContactsManager::add_channel_participants(ChannelId channel_id, const vecto
} }
void ContactsManager::set_channel_participant_status(ChannelId channel_id, DialogId participant_dialog_id, void ContactsManager::set_channel_participant_status(ChannelId channel_id, DialogId participant_dialog_id,
DialogParticipantStatus status, Promise<Unit> &&promise) { td_api::object_ptr<td_api::ChatMemberStatus> &&chat_member_status,
Promise<Unit> &&promise) {
auto c = get_channel(channel_id); auto c = get_channel(channel_id);
if (c == nullptr) { if (c == nullptr) {
return promise.set_error(Status::Error(400, "Chat info not found")); return promise.set_error(Status::Error(400, "Chat info not found"));
} }
auto status = get_dialog_participant_status(chat_member_status, get_channel_type(c));
if (participant_dialog_id == DialogId(get_my_id())) { if (participant_dialog_id == DialogId(get_my_id())) {
// fast path is needed, because get_channel_status may return Creator, while GetChannelParticipantQuery returning Left // fast path is needed, because get_channel_status may return Creator, while GetChannelParticipantQuery returning Left
@ -10505,8 +10507,8 @@ void ContactsManager::on_get_user_full(tl_object_ptr<telegram_api::userFull> &&u
bool can_be_called = user->phone_calls_available_ && !user->phone_calls_private_; bool can_be_called = user->phone_calls_available_ && !user->phone_calls_private_;
bool supports_video_calls = user->video_calls_available_ && !user->phone_calls_private_; bool supports_video_calls = user->video_calls_available_ && !user->phone_calls_private_;
bool has_private_calls = user->phone_calls_private_; bool has_private_calls = user->phone_calls_private_;
AdministratorRights group_administrator_rights(user->bot_group_admin_rights_); AdministratorRights group_administrator_rights(user->bot_group_admin_rights_, ChannelType::Megagroup);
AdministratorRights broadcast_administrator_rights(user->bot_broadcast_admin_rights_); AdministratorRights broadcast_administrator_rights(user->bot_broadcast_admin_rights_, ChannelType::Broadcast);
if (user_full->can_be_called != can_be_called || user_full->supports_video_calls != supports_video_calls || if (user_full->can_be_called != can_be_called || user_full->supports_video_calls != supports_video_calls ||
user_full->has_private_calls != has_private_calls || user_full->has_private_calls != has_private_calls ||
user_full->private_forward_name != user->private_forward_name_ || user_full->private_forward_name != user->private_forward_name_ ||
@ -15122,7 +15124,8 @@ void ContactsManager::add_dialog_participants(DialogId dialog_id, const vector<U
} }
void ContactsManager::set_dialog_participant_status(DialogId dialog_id, DialogId participant_dialog_id, void ContactsManager::set_dialog_participant_status(DialogId dialog_id, DialogId participant_dialog_id,
DialogParticipantStatus &&status, Promise<Unit> &&promise) { td_api::object_ptr<td_api::ChatMemberStatus> &&chat_member_status,
Promise<Unit> &&promise) {
if (!td_->messages_manager_->have_dialog_force(dialog_id, "set_dialog_participant_status")) { if (!td_->messages_manager_->have_dialog_force(dialog_id, "set_dialog_participant_status")) {
return promise.set_error(Status::Error(400, "Chat not found")); return promise.set_error(Status::Error(400, "Chat not found"));
} }
@ -15130,7 +15133,8 @@ void ContactsManager::set_dialog_participant_status(DialogId dialog_id, DialogId
switch (dialog_id.get_type()) { switch (dialog_id.get_type()) {
case DialogType::User: case DialogType::User:
return promise.set_error(Status::Error(400, "Chat member status can't be changed in private chats")); return promise.set_error(Status::Error(400, "Chat member status can't be changed in private chats"));
case DialogType::Chat: case DialogType::Chat: {
auto status = get_dialog_participant_status(chat_member_status, ChannelType::Unknown);
if (participant_dialog_id.get_type() != DialogType::User) { if (participant_dialog_id.get_type() != DialogType::User) {
if (status == DialogParticipantStatus::Left()) { if (status == DialogParticipantStatus::Left()) {
return promise.set_value(Unit()); return promise.set_value(Unit());
@ -15140,9 +15144,10 @@ void ContactsManager::set_dialog_participant_status(DialogId dialog_id, DialogId
} }
return set_chat_participant_status(dialog_id.get_chat_id(), participant_dialog_id.get_user_id(), status, return set_chat_participant_status(dialog_id.get_chat_id(), participant_dialog_id.get_user_id(), status,
std::move(promise)); std::move(promise));
}
case DialogType::Channel: case DialogType::Channel:
return set_channel_participant_status(dialog_id.get_channel_id(), participant_dialog_id, status, return set_channel_participant_status(dialog_id.get_channel_id(), participant_dialog_id,
std::move(promise)); std::move(chat_member_status), std::move(promise));
case DialogType::SecretChat: case DialogType::SecretChat:
return promise.set_error(Status::Error(400, "Chat member status can't be changed in secret chats")); return promise.set_error(Status::Error(400, "Chat member status can't be changed in secret chats"));
case DialogType::None: case DialogType::None:
@ -15168,7 +15173,8 @@ void ContactsManager::ban_dialog_participant(DialogId dialog_id, DialogId partic
std::move(promise)); std::move(promise));
case DialogType::Channel: case DialogType::Channel:
return set_channel_participant_status(dialog_id.get_channel_id(), participant_dialog_id, return set_channel_participant_status(dialog_id.get_channel_id(), participant_dialog_id,
DialogParticipantStatus::Banned(banned_until_date), std::move(promise)); td_api::make_object<td_api::chatMemberStatusBanned>(banned_until_date),
std::move(promise));
case DialogType::SecretChat: case DialogType::SecretChat:
return promise.set_error(Status::Error(400, "Can't ban members in secret chats")); return promise.set_error(Status::Error(400, "Can't ban members in secret chats"));
case DialogType::None: case DialogType::None:
@ -15685,7 +15691,7 @@ void ContactsManager::on_chat_update(telegram_api::chat &chat, const char *sourc
if (is_creator) { if (is_creator) {
return DialogParticipantStatus::Creator(!has_left, false, string()); return DialogParticipantStatus::Creator(!has_left, false, string());
} else if (chat.admin_rights_ != nullptr) { } else if (chat.admin_rights_ != nullptr) {
return DialogParticipantStatus(false, std::move(chat.admin_rights_), string()); return DialogParticipantStatus(false, std::move(chat.admin_rights_), string(), ChannelType::Unknown);
} else if (has_left) { } else if (has_left) {
return DialogParticipantStatus::Left(); return DialogParticipantStatus::Left();
} else { } else {
@ -15864,7 +15870,8 @@ void ContactsManager::on_chat_update(telegram_api::channel &channel, const char
(channel.admin_rights_->flags_ & telegram_api::chatAdminRights::ANONYMOUS_MASK) != 0; (channel.admin_rights_->flags_ & telegram_api::chatAdminRights::ANONYMOUS_MASK) != 0;
return DialogParticipantStatus::Creator(!has_left, is_anonymous, string()); return DialogParticipantStatus::Creator(!has_left, is_anonymous, string());
} else if (channel.admin_rights_ != nullptr) { } else if (channel.admin_rights_ != nullptr) {
return DialogParticipantStatus(false, std::move(channel.admin_rights_), string()); return DialogParticipantStatus(false, std::move(channel.admin_rights_), string(),
is_megagroup ? ChannelType::Megagroup : ChannelType::Broadcast);
} else if (channel.banned_rights_ != nullptr) { } else if (channel.banned_rights_ != nullptr) {
return DialogParticipantStatus(!has_left, std::move(channel.banned_rights_)); return DialogParticipantStatus(!has_left, std::move(channel.banned_rights_));
} else if (has_left) { } else if (has_left) {

View File

@ -537,7 +537,8 @@ class ContactsManager final : public Actor {
void add_dialog_participants(DialogId dialog_id, const vector<UserId> &user_ids, Promise<Unit> &&promise); void add_dialog_participants(DialogId dialog_id, const vector<UserId> &user_ids, Promise<Unit> &&promise);
void set_dialog_participant_status(DialogId dialog_id, DialogId participant_dialog_id, void set_dialog_participant_status(DialogId dialog_id, DialogId participant_dialog_id,
DialogParticipantStatus &&status, Promise<Unit> &&promise); td_api::object_ptr<td_api::ChatMemberStatus> &&chat_member_status,
Promise<Unit> &&promise);
void ban_dialog_participant(DialogId dialog_id, DialogId participant_dialog_id, int32 banned_until_date, void ban_dialog_participant(DialogId dialog_id, DialogId participant_dialog_id, int32 banned_until_date,
bool revoke_messages, Promise<Unit> &&promise); bool revoke_messages, Promise<Unit> &&promise);
@ -1560,12 +1561,6 @@ class ContactsManager final : public Actor {
void update_dialogs_for_discussion(DialogId dialog_id, bool is_suitable); void update_dialogs_for_discussion(DialogId dialog_id, bool is_suitable);
void set_chat_participant_status(ChatId chat_id, UserId user_id, DialogParticipantStatus status,
Promise<Unit> &&promise);
void set_channel_participant_status(ChannelId channel_id, DialogId participant_dialog_id,
DialogParticipantStatus status, Promise<Unit> &&promise);
void send_edit_chat_admin_query(ChatId chat_id, UserId user_id, bool is_administrator, Promise<Unit> &&promise); void send_edit_chat_admin_query(ChatId chat_id, UserId user_id, bool is_administrator, Promise<Unit> &&promise);
void delete_chat_participant(ChatId chat_id, UserId user_id, bool revoke_messages, Promise<Unit> &&promise); void delete_chat_participant(ChatId chat_id, UserId user_id, bool revoke_messages, Promise<Unit> &&promise);
@ -1588,6 +1583,13 @@ class ContactsManager final : public Actor {
const DialogParticipant *get_channel_participant_from_cache(ChannelId channel_id, DialogId participant_dialog_id); const DialogParticipant *get_channel_participant_from_cache(ChannelId channel_id, DialogId participant_dialog_id);
void set_chat_participant_status(ChatId chat_id, UserId user_id, DialogParticipantStatus status,
Promise<Unit> &&promise);
void set_channel_participant_status(ChannelId channel_id, DialogId participant_dialog_id,
td_api::object_ptr<td_api::ChatMemberStatus> &&chat_member_status,
Promise<Unit> &&promise);
void set_channel_participant_status_impl(ChannelId channel_id, DialogId participant_dialog_id, void set_channel_participant_status_impl(ChannelId channel_id, DialogId participant_dialog_id,
DialogParticipantStatus status, DialogParticipantStatus old_status, DialogParticipantStatus status, DialogParticipantStatus old_status,
Promise<Unit> &&promise); Promise<Unit> &&promise);

View File

@ -18,7 +18,8 @@
namespace td { namespace td {
AdministratorRights::AdministratorRights(const tl_object_ptr<telegram_api::chatAdminRights> &rights) { AdministratorRights::AdministratorRights(const tl_object_ptr<telegram_api::chatAdminRights> &rights,
ChannelType channel_type) {
if (rights == nullptr) { if (rights == nullptr) {
flags_ = 0; flags_ = 0;
return; return;
@ -27,12 +28,14 @@ AdministratorRights::AdministratorRights(const tl_object_ptr<telegram_api::chatA
if (!rights->other_) { if (!rights->other_) {
LOG(ERROR) << "Receive wrong other flag in " << to_string(rights); LOG(ERROR) << "Receive wrong other flag in " << to_string(rights);
} }
*this = AdministratorRights(rights->anonymous_, rights->other_, rights->change_info_, rights->post_messages_, *this =
rights->edit_messages_, rights->delete_messages_, rights->invite_users_, AdministratorRights(rights->anonymous_, rights->other_, rights->change_info_, rights->post_messages_,
rights->ban_users_, rights->pin_messages_, rights->add_admins_, rights->manage_call_); rights->edit_messages_, rights->delete_messages_, rights->invite_users_, rights->ban_users_,
rights->pin_messages_, rights->add_admins_, rights->manage_call_, channel_type);
} }
AdministratorRights::AdministratorRights(const td_api::object_ptr<td_api::chatAdministratorRights> &rights) { AdministratorRights::AdministratorRights(const td_api::object_ptr<td_api::chatAdministratorRights> &rights,
ChannelType channel_type) {
if (rights == nullptr) { if (rights == nullptr) {
flags_ = 0; flags_ = 0;
return; return;
@ -40,13 +43,25 @@ AdministratorRights::AdministratorRights(const td_api::object_ptr<td_api::chatAd
*this = AdministratorRights(rights->is_anonymous_, rights->can_manage_chat_, rights->can_change_info_, *this = AdministratorRights(rights->is_anonymous_, rights->can_manage_chat_, rights->can_change_info_,
rights->can_post_messages_, rights->can_edit_messages_, rights->can_delete_messages_, rights->can_post_messages_, rights->can_edit_messages_, rights->can_delete_messages_,
rights->can_invite_users_, rights->can_restrict_members_, rights->can_pin_messages_, rights->can_invite_users_, rights->can_restrict_members_, rights->can_pin_messages_,
rights->can_promote_members_, rights->can_manage_video_chats_); rights->can_promote_members_, rights->can_manage_video_chats_, channel_type);
} }
AdministratorRights::AdministratorRights(bool is_anonymous, bool can_manage_dialog, bool can_change_info, AdministratorRights::AdministratorRights(bool is_anonymous, bool can_manage_dialog, bool can_change_info,
bool can_post_messages, bool can_edit_messages, bool can_delete_messages, 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_invite_users, bool can_restrict_members, bool can_pin_messages,
bool can_promote_members, bool can_manage_calls) { bool can_promote_members, bool can_manage_calls, ChannelType channel_type) {
switch (channel_type) {
case ChannelType::Broadcast:
can_pin_messages = false;
is_anonymous = false;
break;
case ChannelType::Megagroup:
can_post_messages = false;
can_edit_messages = false;
break;
case ChannelType::Unknown:
break;
}
flags_ = (static_cast<uint32>(can_manage_dialog) * CAN_MANAGE_DIALOG) | flags_ = (static_cast<uint32>(can_manage_dialog) * CAN_MANAGE_DIALOG) |
(static_cast<uint32>(can_change_info) * CAN_CHANGE_INFO_AND_SETTINGS) | (static_cast<uint32>(can_change_info) * CAN_CHANGE_INFO_AND_SETTINGS) |
(static_cast<uint32>(can_post_messages) * CAN_POST_MESSAGES) | (static_cast<uint32>(can_post_messages) * CAN_POST_MESSAGES) |
@ -60,6 +75,9 @@ AdministratorRights::AdministratorRights(bool is_anonymous, bool can_manage_dial
(static_cast<uint32>(is_anonymous) * IS_ANONYMOUS); (static_cast<uint32>(is_anonymous) * IS_ANONYMOUS);
if (flags_ != 0) { if (flags_ != 0) {
flags_ |= CAN_MANAGE_DIALOG; flags_ |= CAN_MANAGE_DIALOG;
if (channel_type == ChannelType::Broadcast) {
flags_ |= CAN_RESTRICT_MEMBERS;
}
} }
} }
@ -357,22 +375,24 @@ DialogParticipantStatus DialogParticipantStatus::Banned(int32 banned_until_date)
} }
DialogParticipantStatus DialogParticipantStatus::GroupAdministrator(bool is_creator) { DialogParticipantStatus DialogParticipantStatus::GroupAdministrator(bool is_creator) {
return Administrator(AdministratorRights(false, true, true, false, false, true, true, true, true, false, true), return Administrator(
AdministratorRights(false, true, true, false, false, true, true, true, true, false, true, ChannelType::Unknown),
string(), is_creator); string(), is_creator);
} }
DialogParticipantStatus DialogParticipantStatus::ChannelAdministrator(bool is_creator, bool is_megagroup) { DialogParticipantStatus DialogParticipantStatus::ChannelAdministrator(bool is_creator, bool is_megagroup) {
auto rights = is_megagroup auto rights = is_megagroup ? AdministratorRights(false, true, true, false, false, true, true, true, true, false,
? AdministratorRights(false, true, true, false, false, true, true, true, true, false, false) false, ChannelType::Megagroup)
: AdministratorRights(false, true, false, true, true, true, false, true, false, false, false); : AdministratorRights(false, true, false, true, true, true, false, true, false, false,
false, ChannelType::Broadcast);
return Administrator(rights, string(), is_creator); return Administrator(rights, string(), is_creator);
} }
DialogParticipantStatus::DialogParticipantStatus(bool can_be_edited, DialogParticipantStatus::DialogParticipantStatus(bool can_be_edited,
tl_object_ptr<telegram_api::chatAdminRights> &&admin_rights, tl_object_ptr<telegram_api::chatAdminRights> &&admin_rights,
string rank) { string rank, ChannelType channel_type) {
CHECK(admin_rights != nullptr); CHECK(admin_rights != nullptr);
uint32 flags = AdministratorRights(std::move(admin_rights)).flags_ | AdministratorRights::CAN_MANAGE_DIALOG; uint32 flags = AdministratorRights(admin_rights, channel_type).flags_ | AdministratorRights::CAN_MANAGE_DIALOG;
if (can_be_edited) { if (can_be_edited) {
flags |= CAN_BE_EDITED; flags |= CAN_BE_EDITED;
} }
@ -546,7 +566,8 @@ StringBuilder &operator<<(StringBuilder &string_builder, const DialogParticipant
} }
} }
DialogParticipantStatus get_dialog_participant_status(const tl_object_ptr<td_api::ChatMemberStatus> &status) { DialogParticipantStatus get_dialog_participant_status(const td_api::object_ptr<td_api::ChatMemberStatus> &status,
ChannelType channel_type) {
auto constructor_id = status == nullptr ? td_api::chatMemberStatusMember::ID : status->get_id(); auto constructor_id = status == nullptr ? td_api::chatMemberStatusMember::ID : status->get_id();
switch (constructor_id) { switch (constructor_id) {
case td_api::chatMemberStatusCreator::ID: { case td_api::chatMemberStatusCreator::ID: {
@ -563,8 +584,8 @@ DialogParticipantStatus get_dialog_participant_status(const tl_object_ptr<td_api
if (!clean_input_string(custom_title)) { if (!clean_input_string(custom_title)) {
custom_title.clear(); custom_title.clear();
} }
return DialogParticipantStatus::Administrator(AdministratorRights(st->rights_), std::move(custom_title), return DialogParticipantStatus::Administrator(AdministratorRights(st->rights_, channel_type),
true /*st->can_be_edited_*/); std::move(custom_title), true /*st->can_be_edited_*/);
} }
case td_api::chatMemberStatusMember::ID: case td_api::chatMemberStatusMember::ID:
return DialogParticipantStatus::Member(); return DialogParticipantStatus::Member();
@ -624,7 +645,8 @@ DialogParticipant::DialogParticipant(tl_object_ptr<telegram_api::ChatParticipant
} }
} }
DialogParticipant::DialogParticipant(tl_object_ptr<telegram_api::ChannelParticipant> &&participant_ptr) { DialogParticipant::DialogParticipant(tl_object_ptr<telegram_api::ChannelParticipant> &&participant_ptr,
ChannelType channel_type) {
CHECK(participant_ptr != nullptr); CHECK(participant_ptr != nullptr);
switch (participant_ptr->get_id()) { switch (participant_ptr->get_id()) {
@ -651,7 +673,7 @@ DialogParticipant::DialogParticipant(tl_object_ptr<telegram_api::ChannelParticip
auto participant = move_tl_object_as<telegram_api::channelParticipantAdmin>(participant_ptr); auto participant = move_tl_object_as<telegram_api::channelParticipantAdmin>(participant_ptr);
*this = {DialogId(UserId(participant->user_id_)), UserId(participant->promoted_by_), participant->date_, *this = {DialogId(UserId(participant->user_id_)), UserId(participant->promoted_by_), participant->date_,
DialogParticipantStatus(participant->can_edit_, std::move(participant->admin_rights_), DialogParticipantStatus(participant->can_edit_, std::move(participant->admin_rights_),
std::move(participant->rank_))}; std::move(participant->rank_), channel_type)};
break; break;
} }
case telegram_api::channelParticipantLeft::ID: { case telegram_api::channelParticipantLeft::ID: {

View File

@ -6,6 +6,7 @@
// //
#pragma once #pragma once
#include "td/telegram/ChannelType.h"
#include "td/telegram/DialogId.h" #include "td/telegram/DialogId.h"
#include "td/telegram/MessageId.h" #include "td/telegram/MessageId.h"
#include "td/telegram/td_api.h" #include "td/telegram/td_api.h"
@ -50,14 +51,15 @@ class AdministratorRights {
AdministratorRights() : flags_(0) { AdministratorRights() : flags_(0) {
} }
explicit AdministratorRights(const tl_object_ptr<telegram_api::chatAdminRights> &admin_rights); AdministratorRights(const tl_object_ptr<telegram_api::chatAdminRights> &admin_rights, ChannelType channel_type);
explicit AdministratorRights(const td_api::object_ptr<td_api::chatAdministratorRights> &administrator_rights); AdministratorRights(const td_api::object_ptr<td_api::chatAdministratorRights> &administrator_rights,
ChannelType channel_type);
AdministratorRights(bool is_anonymous, bool can_manage_dialog, bool can_change_info, bool can_post_messages, AdministratorRights(bool is_anonymous, 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_edit_messages, bool can_delete_messages, bool can_invite_users,
bool can_restrict_members, bool can_pin_messages, bool can_promote_members, bool can_restrict_members, bool can_pin_messages, bool can_promote_members, bool can_manage_calls,
bool can_manage_calls); ChannelType channel_type);
telegram_api::object_ptr<telegram_api::chatAdminRights> get_chat_admin_rights() const; telegram_api::object_ptr<telegram_api::chatAdminRights> get_chat_admin_rights() const;
@ -289,8 +291,11 @@ class DialogParticipantStatus {
// legacy rights // legacy rights
static DialogParticipantStatus ChannelAdministrator(bool is_creator, bool is_megagroup); static DialogParticipantStatus ChannelAdministrator(bool is_creator, bool is_megagroup);
DialogParticipantStatus(bool can_be_edited, tl_object_ptr<telegram_api::chatAdminRights> &&admin_rights, string rank); // forcely returns an administrator
DialogParticipantStatus(bool can_be_edited, tl_object_ptr<telegram_api::chatAdminRights> &&admin_rights, string rank,
ChannelType channel_type);
// forcely returns a restricted or banned
DialogParticipantStatus(bool is_member, tl_object_ptr<telegram_api::chatBannedRights> &&banned_rights); DialogParticipantStatus(bool is_member, tl_object_ptr<telegram_api::chatBannedRights> &&banned_rights);
RestrictedRights get_effective_restricted_rights() const; RestrictedRights get_effective_restricted_rights() const;
@ -496,7 +501,8 @@ struct DialogParticipant {
DialogParticipant(tl_object_ptr<telegram_api::ChatParticipant> &&participant_ptr, int32 chat_creation_date, DialogParticipant(tl_object_ptr<telegram_api::ChatParticipant> &&participant_ptr, int32 chat_creation_date,
bool is_creator); bool is_creator);
explicit DialogParticipant(tl_object_ptr<telegram_api::ChannelParticipant> &&participant_ptr); DialogParticipant(tl_object_ptr<telegram_api::ChannelParticipant> &&participant_ptr,
ChannelType channel_type = ChannelType::Unknown);
static DialogParticipant left(DialogId dialog_id) { static DialogParticipant left(DialogId dialog_id) {
return {dialog_id, UserId(), 0, DialogParticipantStatus::Left()}; return {dialog_id, UserId(), 0, DialogParticipantStatus::Left()};
@ -546,6 +552,7 @@ struct DialogParticipants {
td_api::object_ptr<td_api::chatMembers> get_chat_members_object(Td *td) const; td_api::object_ptr<td_api::chatMembers> get_chat_members_object(Td *td) const;
}; };
DialogParticipantStatus get_dialog_participant_status(const tl_object_ptr<td_api::ChatMemberStatus> &status); DialogParticipantStatus get_dialog_participant_status(const td_api::object_ptr<td_api::ChatMemberStatus> &status,
ChannelType channel_type);
} // namespace td } // namespace td

View File

@ -8,6 +8,7 @@
#include "td/telegram/AccessRights.h" #include "td/telegram/AccessRights.h"
#include "td/telegram/ChannelId.h" #include "td/telegram/ChannelId.h"
#include "td/telegram/ChannelType.h"
#include "td/telegram/ConfigManager.h" #include "td/telegram/ConfigManager.h"
#include "td/telegram/ConfigShared.h" #include "td/telegram/ConfigShared.h"
#include "td/telegram/ContactsManager.h" #include "td/telegram/ContactsManager.h"
@ -140,20 +141,10 @@ static AdministratorRights get_administrator_rights(Slice rights, bool for_chann
can_manage_dialog = true; can_manage_dialog = true;
} }
} }
if (for_channel) {
can_pin_messages = false;
is_anonymous = false;
if (can_manage_dialog || can_change_info || can_post_messages || can_edit_messages || can_delete_messages ||
can_invite_users || can_promote_members || can_manage_calls) {
can_restrict_members = true;
}
} else {
can_post_messages = false;
can_edit_messages = false;
}
return AdministratorRights(is_anonymous, can_manage_dialog, can_change_info, can_post_messages, can_edit_messages, return AdministratorRights(is_anonymous, 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_delete_messages, can_invite_users, can_restrict_members, can_pin_messages,
can_promote_members, can_manage_calls); can_promote_members, can_manage_calls,
for_channel ? ChannelType::Broadcast : ChannelType::Megagroup);
} }
class LinkManager::InternalLinkActiveSessions final : public InternalLink { class LinkManager::InternalLinkActiveSessions final : public InternalLink {

View File

@ -20,6 +20,7 @@
#include "td/telegram/CallId.h" #include "td/telegram/CallId.h"
#include "td/telegram/CallManager.h" #include "td/telegram/CallManager.h"
#include "td/telegram/ChannelId.h" #include "td/telegram/ChannelId.h"
#include "td/telegram/ChannelType.h"
#include "td/telegram/ChatId.h" #include "td/telegram/ChatId.h"
#include "td/telegram/ConfigManager.h" #include "td/telegram/ConfigManager.h"
#include "td/telegram/ConfigShared.h" #include "td/telegram/ConfigShared.h"
@ -6204,7 +6205,7 @@ void Td::on_request(uint64 id, const td_api::joinChat &request) {
void Td::on_request(uint64 id, const td_api::leaveChat &request) { void Td::on_request(uint64 id, const td_api::leaveChat &request) {
CREATE_OK_REQUEST_PROMISE(); CREATE_OK_REQUEST_PROMISE();
DialogId dialog_id(request.chat_id_); DialogId dialog_id(request.chat_id_);
auto new_status = DialogParticipantStatus::Left(); td_api::object_ptr<td_api::ChatMemberStatus> new_status = td_api::make_object<td_api::chatMemberStatusLeft>();
if (dialog_id.get_type() == DialogType::Channel && messages_manager_->have_dialog_force(dialog_id, "leaveChat")) { if (dialog_id.get_type() == DialogType::Channel && messages_manager_->have_dialog_force(dialog_id, "leaveChat")) {
auto status = contacts_manager_->get_channel_status(dialog_id.get_channel_id()); auto status = contacts_manager_->get_channel_status(dialog_id.get_channel_id());
if (status.is_creator()) { if (status.is_creator()) {
@ -6212,8 +6213,8 @@ void Td::on_request(uint64 id, const td_api::leaveChat &request) {
return promise.set_value(Unit()); return promise.set_value(Unit());
} }
auto rank = status.get_rank(); new_status =
new_status = DialogParticipantStatus::Creator(false, status.is_anonymous(), std::move(rank)); td_api::make_object<td_api::chatMemberStatusCreator>(status.get_rank(), status.is_anonymous(), false);
} }
} }
contacts_manager_->set_dialog_participant_status(dialog_id, DialogId(contacts_manager_->get_my_id()), contacts_manager_->set_dialog_participant_status(dialog_id, DialogId(contacts_manager_->get_my_id()),
@ -6234,12 +6235,12 @@ void Td::on_request(uint64 id, const td_api::addChatMembers &request) {
std::move(promise)); std::move(promise));
} }
void Td::on_request(uint64 id, const td_api::setChatMemberStatus &request) { void Td::on_request(uint64 id, td_api::setChatMemberStatus &request) {
CREATE_OK_REQUEST_PROMISE(); CREATE_OK_REQUEST_PROMISE();
TRY_RESULT_PROMISE(promise, participant_dialog_id, TRY_RESULT_PROMISE(promise, participant_dialog_id,
get_message_sender_dialog_id(this, request.member_id_, false, false)); get_message_sender_dialog_id(this, request.member_id_, false, false));
contacts_manager_->set_dialog_participant_status(DialogId(request.chat_id_), participant_dialog_id, contacts_manager_->set_dialog_participant_status(DialogId(request.chat_id_), participant_dialog_id,
get_dialog_participant_status(request.status_), std::move(promise)); std::move(request.status_), std::move(promise));
} }
void Td::on_request(uint64 id, const td_api::banChatMember &request) { void Td::on_request(uint64 id, const td_api::banChatMember &request) {
@ -6792,14 +6793,16 @@ void Td::on_request(uint64 id, td_api::getCommands &request) {
void Td::on_request(uint64 id, const td_api::setDefaultGroupAdministratorRights &request) { void Td::on_request(uint64 id, const td_api::setDefaultGroupAdministratorRights &request) {
CHECK_IS_BOT(); CHECK_IS_BOT();
CREATE_OK_REQUEST_PROMISE(); CREATE_OK_REQUEST_PROMISE();
set_default_group_administrator_rights(this, AdministratorRights(request.default_group_administrator_rights_), set_default_group_administrator_rights(
this, AdministratorRights(request.default_group_administrator_rights_, ChannelType::Megagroup),
std::move(promise)); std::move(promise));
} }
void Td::on_request(uint64 id, const td_api::setDefaultChannelAdministratorRights &request) { void Td::on_request(uint64 id, const td_api::setDefaultChannelAdministratorRights &request) {
CHECK_IS_BOT(); CHECK_IS_BOT();
CREATE_OK_REQUEST_PROMISE(); CREATE_OK_REQUEST_PROMISE();
set_default_channel_administrator_rights(this, AdministratorRights(request.default_channel_administrator_rights_), set_default_channel_administrator_rights(
this, AdministratorRights(request.default_channel_administrator_rights_, ChannelType::Broadcast),
std::move(promise)); std::move(promise));
} }

View File

@ -873,7 +873,7 @@ class Td final : public Actor {
void on_request(uint64 id, const td_api::addChatMembers &request); void on_request(uint64 id, const td_api::addChatMembers &request);
void on_request(uint64 id, const td_api::setChatMemberStatus &request); void on_request(uint64 id, td_api::setChatMemberStatus &request);
void on_request(uint64 id, const td_api::banChatMember &request); void on_request(uint64 id, const td_api::banChatMember &request);