Drop channel invite link, only when corresponding administrator right is removed.

This commit is contained in:
levlam 2021-03-28 02:35:11 +03:00
parent 024601eb86
commit 984e79b7f7
4 changed files with 32 additions and 25 deletions

View File

@ -2292,7 +2292,7 @@ class InviteToChannelQuery : public Td::ResultHandler {
auto ptr = result_ptr.move_as_ok();
LOG(INFO) << "Receive result for InviteToChannelQuery: " << to_string(ptr);
td->contacts_manager_->invalidate_channel_full(channel_id_, false, false);
td->contacts_manager_->invalidate_channel_full(channel_id_, false);
td->updates_manager_->on_get_updates(std::move(ptr), std::move(promise_));
}
@ -2327,7 +2327,7 @@ class EditChannelAdminQuery : public Td::ResultHandler {
auto ptr = result_ptr.move_as_ok();
LOG(INFO) << "Receive result for EditChannelAdminQuery: " << to_string(ptr);
td->contacts_manager_->invalidate_channel_full(channel_id_, false, false);
td->contacts_manager_->invalidate_channel_full(channel_id_, false);
td->updates_manager_->on_get_updates(std::move(ptr), std::move(promise_));
}
@ -2362,7 +2362,7 @@ class EditChannelBannedQuery : public Td::ResultHandler {
auto ptr = result_ptr.move_as_ok();
LOG(INFO) << "Receive result for EditChannelBannedQuery: " << to_string(ptr);
td->contacts_manager_->invalidate_channel_full(channel_id_, false, false);
td->contacts_manager_->invalidate_channel_full(channel_id_, false);
td->updates_manager_->on_get_updates(std::move(ptr), std::move(promise_));
}
@ -2468,7 +2468,7 @@ class EditChannelCreatorQuery : public Td::ResultHandler {
auto ptr = result_ptr.move_as_ok();
LOG(INFO) << "Receive result for EditChannelCreatorQuery: " << to_string(ptr);
td->contacts_manager_->invalidate_channel_full(channel_id_, false, false);
td->contacts_manager_->invalidate_channel_full(channel_id_, false);
td->updates_manager_->on_get_updates(std::move(ptr), std::move(promise_));
}
@ -3518,7 +3518,7 @@ void ContactsManager::on_channel_unban_timeout(ChannelId channel_id) {
LOG(INFO) << "Update " << channel_id << " status";
c->is_status_changed = true;
invalidate_channel_full(channel_id, false, !c->is_slow_mode_enabled);
invalidate_channel_full(channel_id, !c->is_slow_mode_enabled);
update_channel(c, channel_id); // always call, because in case of failure we need to reactivate timeout
}
@ -7135,8 +7135,7 @@ Status ContactsManager::can_manage_dialog_invite_links(DialogId dialog_id, bool
if (!c->is_active) {
return Status::Error(3, "Chat is deactivated");
}
auto status = get_chat_status(c);
bool have_rights = creator_only ? status.is_creator() : status.is_administrator() && status.can_invite_users();
bool have_rights = creator_only ? c->status.is_creator() : c->status.can_manage_invite_links();
if (!have_rights) {
return Status::Error(3, "Not enough rights to manage chat invite link");
}
@ -7147,8 +7146,7 @@ Status ContactsManager::can_manage_dialog_invite_links(DialogId dialog_id, bool
if (c == nullptr) {
return Status::Error(3, "Chat info not found");
}
auto status = get_channel_status(c);
bool have_rights = creator_only ? status.is_creator() : status.is_administrator() && status.can_invite_users();
bool have_rights = creator_only ? c->status.is_creator() : c->status.can_manage_invite_links();
if (!have_rights) {
return Status::Error(3, "Not enough rights to manage chat invite link");
}
@ -11510,7 +11508,7 @@ bool ContactsManager::on_get_channel_error(ChannelId channel_id, const Status &s
remove_dialog_access_by_invite_link(DialogId(channel_id));
}
invalidate_channel_full(channel_id, false, !c->is_slow_mode_enabled);
invalidate_channel_full(channel_id, !c->is_slow_mode_enabled);
LOG_IF(ERROR, have_input_peer_channel(c, channel_id, AccessRights::Read))
<< "Have read access to channel after receiving CHANNEL_PRIVATE. Channel state: "
<< oneline(to_string(get_supergroup_object(channel_id, c)))
@ -11760,7 +11758,7 @@ void ContactsManager::speculative_add_channel_participants(ChannelId channel_id,
bool by_me) {
if (by_me) {
// Currently ignore all changes made by the current user, because they may be already counted
invalidate_channel_full(channel_id, false, false); // just in case
invalidate_channel_full(channel_id, false); // just in case
return;
}
@ -11911,16 +11909,12 @@ void ContactsManager::drop_channel_photos(ChannelId channel_id, bool is_empty, b
}
}
void ContactsManager::invalidate_channel_full(ChannelId channel_id, bool need_drop_invite_link,
bool need_drop_slow_mode_delay) {
void ContactsManager::invalidate_channel_full(ChannelId channel_id, bool need_drop_slow_mode_delay) {
LOG(INFO) << "Invalidate supergroup full for " << channel_id;
// drop channel full cache
auto channel_full = get_channel_full_force(channel_id, "invalidate_channel_full");
if (channel_full != nullptr) {
channel_full->expires_at = 0.0;
if (need_drop_invite_link) {
on_update_channel_full_invite_link(channel_full, nullptr);
}
if (need_drop_slow_mode_delay && channel_full->slow_mode_delay != 0) {
channel_full->slow_mode_delay = 0;
channel_full->slow_mode_next_send_date = 0;
@ -12909,10 +12903,17 @@ void ContactsManager::on_channel_status_changed(Channel *c, ChannelId channel_id
const DialogParticipantStatus &new_status) {
CHECK(c->is_update_supergroup_sent);
bool need_drop_invite_link = old_status.is_administrator() != new_status.is_administrator() ||
old_status.is_member() != new_status.is_member();
bool need_reload_group_call = old_status.can_manage_calls() != new_status.can_manage_calls();
invalidate_channel_full(channel_id, need_drop_invite_link, !c->is_slow_mode_enabled);
if (old_status.can_manage_invite_links() && !new_status.can_manage_invite_links()) {
auto channel_full = get_channel_full_force(channel_id, "on_channel_status_changed");
if (channel_full != nullptr) {
on_update_channel_full_invite_link(channel_full, nullptr);
invalidate_channel_full(channel_id, !c->is_slow_mode_enabled);
update_channel_full(channel_full, channel_id);
}
} else {
invalidate_channel_full(channel_id, !c->is_slow_mode_enabled);
}
if (old_status.is_creator() != new_status.is_creator()) {
for (size_t i = 0; i < 2; i++) {
@ -12924,6 +12925,7 @@ void ContactsManager::on_channel_status_changed(Channel *c, ChannelId channel_id
reload_dialog_administrators(DialogId(channel_id), 0, Auto());
remove_dialog_suggested_action(SuggestedAction{SuggestedAction::Type::ConvertToGigagroup, DialogId(channel_id)});
}
if (old_status.is_member() != new_status.is_member() || new_status.is_banned()) {
remove_dialog_access_by_invite_link(DialogId(channel_id));
}
@ -12976,7 +12978,7 @@ void ContactsManager::on_channel_username_changed(Channel *c, ChannelId channel_
const string &new_username) {
if (old_username.empty() || new_username.empty()) {
// moving channel from private to public can change availability of chat members
invalidate_channel_full(channel_id, true, !c->is_slow_mode_enabled);
invalidate_channel_full(channel_id, !c->is_slow_mode_enabled);
}
}
@ -15220,7 +15222,7 @@ void ContactsManager::on_chat_update(telegram_api::channel &channel, const char
c->is_gigagroup = is_gigagroup;
c->is_changed = true;
invalidate_channel_full(channel_id, false, !c->is_slow_mode_enabled);
invalidate_channel_full(channel_id, !c->is_slow_mode_enabled);
}
if (c->is_verified != is_verified || c->sign_messages != sign_messages) {
c->is_verified = is_verified;
@ -15311,7 +15313,7 @@ void ContactsManager::on_chat_update(telegram_api::channel &channel, const char
}
if (need_invalidate_channel_full) {
invalidate_channel_full(channel_id, false, !c->is_slow_mode_enabled);
invalidate_channel_full(channel_id, !c->is_slow_mode_enabled);
}
bool has_active_group_call = (channel.flags_ & CHANNEL_FLAG_HAS_ACTIVE_GROUP_CALL) != 0;
@ -15420,7 +15422,7 @@ void ContactsManager::on_chat_update(telegram_api::channelForbidden &channel, co
}
}
if (need_invalidate_channel_full) {
invalidate_channel_full(channel_id, false, !c->is_slow_mode_enabled);
invalidate_channel_full(channel_id, !c->is_slow_mode_enabled);
}
}

View File

@ -233,7 +233,7 @@ class ContactsManager : public Actor {
void speculative_delete_channel_participant(ChannelId channel_id, UserId deleted_user_id, bool by_me);
void invalidate_channel_full(ChannelId channel_id, bool need_drop_invite_link, bool need_drop_slow_mode_delay);
void invalidate_channel_full(ChannelId channel_id, bool need_drop_slow_mode_delay);
bool on_get_channel_error(ChannelId channel_id, const Status &status, const string &source);

View File

@ -235,6 +235,11 @@ class DialogParticipantStatus {
return (flags_ & CAN_INVITE_USERS_ADMIN) != 0 || (flags_ & CAN_INVITE_USERS_BANNED) != 0;
}
bool can_manage_invite_links() const {
// invite links can be managed, only if administrator was explicitly granted the right
return (flags_ & CAN_INVITE_USERS_ADMIN) != 0;
}
bool can_restrict_members() const {
return (flags_ & CAN_RESTRICT_MEMBERS) != 0;
}

View File

@ -2213,7 +2213,7 @@ void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateChannelTooLong>
}
void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateChannel> update, Promise<Unit> &&promise) {
td_->contacts_manager_->invalidate_channel_full(ChannelId(update->channel_id_), false, false);
td_->contacts_manager_->invalidate_channel_full(ChannelId(update->channel_id_), false);
promise.set_value(Unit());
}