New chat permissions checking.

GitOrigin-RevId: ef555c6cb407efbf3092cda554b1992155c6e1e4
This commit is contained in:
levlam 2019-03-22 18:18:46 +03:00
parent 046be9b785
commit e83184f9fc
4 changed files with 47 additions and 50 deletions

View File

@ -4068,7 +4068,7 @@ void ContactsManager::set_chat_description(ChatId chat_id, const string &descrip
if (c == nullptr) {
return promise.set_error(Status::Error(6, "Chat info not found"));
}
if (!get_chat_status(c).can_change_info_and_settings()) {
if (!get_chat_permissions(c).can_change_info_and_settings()) {
return promise.set_error(Status::Error(6, "Not enough rights to set chat description"));
}
@ -4106,7 +4106,7 @@ void ContactsManager::set_channel_sticker_set(ChannelId channel_id, int64 sticke
if (!c->is_megagroup) {
return promise.set_error(Status::Error(6, "Chat sticker set can be set only for supergroups"));
}
if (!get_channel_status(c).can_change_info_and_settings()) {
if (!get_channel_permissions(c).can_change_info_and_settings()) {
return promise.set_error(Status::Error(6, "Not enough rights to change supergroup sticker set"));
}
@ -4137,7 +4137,7 @@ void ContactsManager::toggle_channel_sign_messages(ChannelId channel_id, bool si
if (get_channel_type(c) == ChannelType::Megagroup) {
return promise.set_error(Status::Error(6, "Message signatures can't be toggled in supergroups"));
}
if (!get_channel_status(c).can_change_info_and_settings()) {
if (!get_channel_permissions(c).can_change_info_and_settings()) {
return promise.set_error(Status::Error(6, "Not enough rights to toggle channel sign messages"));
}
@ -4150,7 +4150,7 @@ void ContactsManager::toggle_channel_is_all_history_available(ChannelId channel_
if (c == nullptr) {
return promise.set_error(Status::Error(6, "Supergroup not found"));
}
if (!get_channel_status(c).can_change_info_and_settings()) {
if (!get_channel_permissions(c).can_change_info_and_settings()) {
return promise.set_error(Status::Error(6, "Not enough rights to toggle all supergroup history availability"));
}
if (get_channel_type(c) != ChannelType::Megagroup) {
@ -4168,7 +4168,7 @@ void ContactsManager::set_channel_description(ChannelId channel_id, const string
if (c == nullptr) {
return promise.set_error(Status::Error(6, "Chat info not found"));
}
if (!get_channel_status(c).can_change_info_and_settings()) {
if (!get_channel_permissions(c).can_change_info_and_settings()) {
return promise.set_error(Status::Error(6, "Not enough rights to set chat description"));
}
@ -4238,7 +4238,7 @@ void ContactsManager::add_chat_participant(ChatId chat_id, UserId user_id, int32
return promise.set_error(Status::Error(3, "Can't forward negative number of messages"));
}
if (user_id != get_my_id()) {
if (!get_chat_status(c).can_invite_users()) {
if (!get_chat_permissions(c).can_invite_users()) {
return promise.set_error(Status::Error(3, "Not enough rights to invite members to the group chat"));
}
} else if (c->status.is_banned()) {
@ -4280,8 +4280,7 @@ void ContactsManager::add_channel_participant(ChannelId channel_id, UserId user_
return;
}
// TODO !(c->anyone_can_invite && get_channel_status(c).is_member())
if (!get_channel_status(c).can_invite_users()) {
if (!get_channel_permissions(c).can_invite_users()) {
return promise.set_error(Status::Error(3, "Not enough rights to invite members to the supergroup chat"));
}
@ -4302,8 +4301,7 @@ void ContactsManager::add_channel_participants(ChannelId channel_id, const vecto
return promise.set_error(Status::Error(3, "Chat info not found"));
}
// TODO !(c->anyone_can_invite && get_channel_status(c).is_member())
if (!get_channel_status(c).can_invite_users()) {
if (!get_channel_permissions(c).can_invite_users()) {
return promise.set_error(Status::Error(3, "Not enough rights to invite members to the supergroup chat"));
}
@ -4449,7 +4447,7 @@ void ContactsManager::promote_channel_participant(ChannelId channel_id, UserId u
CHECK(status.is_member());
// allow to demote self. TODO is it allowed server-side?
} else {
if (!get_channel_status(c).can_promote_members()) {
if (!get_channel_permissions(c).can_promote_members()) {
return promise.set_error(Status::Error(3, "Not enough rights"));
}
}
@ -4474,7 +4472,7 @@ void ContactsManager::change_chat_participant_status(ChatId chat_id, UserId user
return promise.set_error(Status::Error(6, "Chat info not found"));
}
if (!get_chat_status(c).can_promote_members()) {
if (!get_chat_permissions(c).can_promote_members()) {
return promise.set_error(Status::Error(3, "Need creator rights in the group chat"));
}
@ -4507,7 +4505,7 @@ void ContactsManager::export_chat_invite_link(ChatId chat_id, Promise<Unit> &&pr
return promise.set_error(Status::Error(3, "Chat is deactivated"));
}
if (!get_chat_status(c).can_invite_users()) {
if (!get_chat_permissions(c).can_invite_users()) {
return promise.set_error(Status::Error(3, "Not enough rights to export chat invite link"));
}
@ -4584,7 +4582,7 @@ void ContactsManager::delete_chat_participant(ChatId chat_id, UserId user_id, Pr
}
}
if (user_id != my_id) {
auto my_status = get_chat_status(c);
auto my_status = get_chat_permissions(c);
if (!my_status.is_creator()) { // creator can delete anyone
auto participant = get_chat_participant(chat_id, user_id);
if (participant != nullptr) { // if have no information about participant, just send request to the server
@ -4658,7 +4656,7 @@ void ContactsManager::restrict_channel_participant(ChannelId channel_id, UserId
return promise.set_error(Status::Error(3, "Not enough rights to restrict chat creator"));
}
if (!get_channel_status(c).can_restrict_members()) {
if (!get_channel_permissions(c).can_restrict_members()) {
return promise.set_error(Status::Error(3, "Not enough rights to restrict/unrestrict chat member"));
}

View File

@ -24,7 +24,7 @@ int32 DialogParticipantStatus::fix_until_date(int32 date) {
DialogParticipantStatus DialogParticipantStatus::Creator(bool is_member) {
return DialogParticipantStatus(Type::Creator,
ALL_ADMINISTRATOR_RIGHTS | ALL_RESTRICTED_RIGHTS | (is_member ? IS_MEMBER : 0), 0);
ALL_ADMINISTRATOR_RIGHTS | ALL_PERMISSION_RIGHTS | (is_member ? IS_MEMBER : 0), 0);
}
DialogParticipantStatus DialogParticipantStatus::Administrator(bool can_be_edited, bool can_change_info,
@ -48,7 +48,7 @@ DialogParticipantStatus DialogParticipantStatus::Administrator(bool can_be_edite
}
DialogParticipantStatus DialogParticipantStatus::Member() {
return DialogParticipantStatus(Type::Member, IS_MEMBER | ALL_RESTRICTED_RIGHTS, 0);
return DialogParticipantStatus(Type::Member, IS_MEMBER | ALL_PERMISSION_RIGHTS, 0);
}
DialogParticipantStatus DialogParticipantStatus::Restricted(
@ -67,14 +67,14 @@ DialogParticipantStatus DialogParticipantStatus::Restricted(
(static_cast<uint32>(can_invite_users) * CAN_INVITE_USERS_BANNED) |
(static_cast<uint32>(can_pin_messages) * CAN_PIN_MESSAGES_BANNED) |
(static_cast<uint32>(is_member) * IS_MEMBER);
if (flags == (IS_MEMBER | ALL_RESTRICTED_RIGHTS)) {
if (flags == (IS_MEMBER | ALL_PERMISSION_RIGHTS)) {
return Member();
}
return DialogParticipantStatus(Type::Restricted, flags, fix_until_date(restricted_until_date));
}
DialogParticipantStatus DialogParticipantStatus::Left() {
return DialogParticipantStatus(Type::Left, ALL_RESTRICTED_RIGHTS, 0);
return DialogParticipantStatus(Type::Left, ALL_PERMISSION_RIGHTS, 0);
}
DialogParticipantStatus DialogParticipantStatus::Banned(int32 banned_until_date) {
@ -210,13 +210,13 @@ DialogParticipantStatus DialogParticipantStatus::apply_restrictions(RestrictedRi
case Type::Administrator:
// administrators aren't affected by restrictions, but if everyone can invite users,
// pin messages or change info, they also can do that
flags &= ~ALL_ADMIN_RESTRICTED_RIGHTS | default_restrictions.flags_;
flags |= default_restrictions.flags_ & ALL_ADMIN_PERMISSION_RIGHTS;
break;
case Type::Member:
case Type::Restricted:
case Type::Left:
// members and restricted are affected by default restrictions
flags &= ~ALL_RESTRICTED_RIGHTS | default_restrictions.flags_;
flags &= ~ALL_PERMISSION_RIGHTS | default_restrictions.flags_;
break;
case Type::Banned:
// banned can do nothing, even restirctions allows them to do that
@ -238,7 +238,7 @@ void DialogParticipantStatus::update_restrictions() const {
} else {
type_ = Type::Left;
}
flags_ |= ALL_RESTRICTED_RIGHTS;
flags_ |= ALL_PERMISSION_RIGHTS;
} else if (type_ == Type::Banned) {
type_ = Type::Left;
} else {

View File

@ -143,12 +143,14 @@ class DialogParticipantStatus {
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;
static constexpr uint32 ALL_ADMIN_RESTRICTED_RIGHTS =
static constexpr uint32 ALL_ADMIN_PERMISSION_RIGHTS =
CAN_CHANGE_INFO_AND_SETTINGS_BANNED | CAN_INVITE_USERS_BANNED | CAN_PIN_MESSAGES_BANNED;
static constexpr uint32 ALL_RESTRICTED_RIGHTS =
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 | ALL_ADMIN_RESTRICTED_RIGHTS;
static constexpr uint32 ALL_RESTRICTED_RIGHTS = 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;
static constexpr uint32 ALL_PERMISSION_RIGHTS = ALL_RESTRICTED_RIGHTS | ALL_ADMIN_PERMISSION_RIGHTS;
enum class Type : int32 { Creator, Administrator, Member, Restricted, Left, Banned };
// all fields are logically const, but should be updated in update_restrictions()

View File

@ -7534,7 +7534,7 @@ void MessagesManager::delete_messages(DialogId dialog_id, const vector<MessageId
}
break;
case DialogType::Channel: {
auto dialog_status = td_->contacts_manager_->get_channel_status(dialog_id.get_channel_id());
auto dialog_status = td_->contacts_manager_->get_channel_permissions(dialog_id.get_channel_id());
for (auto message_id : message_ids) {
if (!can_delete_channel_message(dialog_status, get_message(d, message_id), is_bot)) {
return promise.set_error(Status::Error(6, "Message can't be deleted"));
@ -7879,7 +7879,7 @@ void MessagesManager::delete_dialog_messages_from_user(DialogId dialog_id, UserI
if (channel_type != ChannelType::Megagroup) {
return promise.set_error(Status::Error(3, "The method is available only for supergroup chats"));
}
channel_status = td_->contacts_manager_->get_channel_status(channel_id);
channel_status = td_->contacts_manager_->get_channel_permissions(channel_id);
if (!channel_status.can_delete_messages()) {
return promise.set_error(Status::Error(5, "Need delete messages administator right in the supergroup chat"));
}
@ -15247,7 +15247,7 @@ tl_object_ptr<td_api::message> MessagesManager::get_message_object(DialogId dial
auto dialog_type = dialog_id.get_type();
auto is_bot = td_->auth_manager_->is_bot();
if (dialog_type == DialogType::Channel) {
auto dialog_status = td_->contacts_manager_->get_channel_status(dialog_id.get_channel_id());
auto dialog_status = td_->contacts_manager_->get_channel_permissions(dialog_id.get_channel_id());
can_delete = can_delete_channel_message(dialog_status, message, is_bot);
}
@ -15409,7 +15409,7 @@ Status MessagesManager::can_send_message(DialogId dialog_id) const {
if (dialog_id.get_type() == DialogType::Channel) {
auto channel_id = dialog_id.get_channel_id();
auto channel_type = td_->contacts_manager_->get_channel_type(channel_id);
auto channel_status = td_->contacts_manager_->get_channel_status(channel_id);
auto channel_status = td_->contacts_manager_->get_channel_permissions(channel_id);
switch (channel_type) {
case ChannelType::Unknown:
@ -15458,7 +15458,7 @@ Status MessagesManager::can_send_message_content(DialogId dialog_id, const Messa
// ok
break;
case DialogType::Channel: {
auto channel_status = td_->contacts_manager_->get_channel_status(dialog_id.get_channel_id());
auto channel_status = td_->contacts_manager_->get_channel_permissions(dialog_id.get_channel_id());
can_send_messages = channel_status.can_send_messages();
can_send_media = channel_status.can_send_media();
can_send_stickers = channel_status.can_send_stickers();
@ -16541,7 +16541,7 @@ Result<MessageId> MessagesManager::send_bot_start_message(UserId bot_user_id, Di
if (!td_->contacts_manager_->have_input_peer_chat(chat_id, AccessRights::Write)) {
return Status::Error(3, "Can't access the chat");
}
auto status = td_->contacts_manager_->get_chat_status(chat_id);
auto status = td_->contacts_manager_->get_chat_permissions(chat_id);
if (!status.can_invite_users()) {
return Status::Error(3, "Need administrator rights to invite a bot to the group chat");
}
@ -16564,7 +16564,7 @@ Result<MessageId> MessagesManager::send_bot_start_message(UserId bot_user_id, Di
default:
UNREACHABLE();
}
auto status = td_->contacts_manager_->get_channel_status(channel_id);
auto status = td_->contacts_manager_->get_channel_permissions(channel_id);
if (!status.can_invite_users()) {
return Status::Error(3, "Need administrator rights to invite a bot to the supergroup chat");
}
@ -16684,7 +16684,7 @@ Result<MessageId> MessagesManager::send_inline_query_result_message(DialogId dia
// ok
break;
case DialogType::Channel: {
auto channel_status = td_->contacts_manager_->get_channel_status(dialog_id.get_channel_id());
auto channel_status = td_->contacts_manager_->get_channel_permissions(dialog_id.get_channel_id());
if (!channel_status.can_use_inline_bots()) {
return Status::Error(400, "Can't use inline bots in the chat");
}
@ -16848,7 +16848,7 @@ bool MessagesManager::can_edit_message(DialogId dialog_id, const Message *m, boo
}
auto channel_id = dialog_id.get_channel_id();
auto channel_status = td_->contacts_manager_->get_channel_status(channel_id);
auto channel_status = td_->contacts_manager_->get_channel_permissions(channel_id);
if (m->is_channel_post) {
if (!channel_status.can_edit_messages() && !(channel_status.can_post_messages() && m->is_outgoing)) {
return false;
@ -17562,7 +17562,7 @@ bool MessagesManager::can_set_game_score(DialogId dialog_id, const Message *m) c
break;
}
auto channel_id = dialog_id.get_channel_id();
auto channel_status = td_->contacts_manager_->get_channel_status(channel_id);
auto channel_status = td_->contacts_manager_->get_channel_permissions(channel_id);
if (m->is_channel_post) {
if (!channel_status.can_edit_messages() && !(channel_status.can_post_messages() && m->is_outgoing)) {
return false;
@ -20955,10 +20955,8 @@ bool MessagesManager::is_update_about_username_change_received(DialogId dialog_i
return td_->contacts_manager_->is_update_about_username_change_received(dialog_id.get_user_id());
case DialogType::Chat:
return true;
case DialogType::Channel: {
auto status = td_->contacts_manager_->get_channel_status(dialog_id.get_channel_id());
return status.is_member();
}
case DialogType::Channel:
return td_->contacts_manager_->get_channel_status(dialog_id.get_channel_id()).is_member();
case DialogType::SecretChat:
return true;
case DialogType::None:
@ -21420,7 +21418,7 @@ void MessagesManager::set_dialog_photo(DialogId dialog_id, const tl_object_ptr<t
return promise.set_error(Status::Error(3, "Can't change private chat photo"));
case DialogType::Chat: {
auto chat_id = dialog_id.get_chat_id();
auto status = td_->contacts_manager_->get_chat_status(chat_id);
auto status = td_->contacts_manager_->get_chat_permissions(chat_id);
if (!status.can_change_info_and_settings() ||
(td_->auth_manager_->is_bot() && !td_->contacts_manager_->is_appointed_chat_administrator(chat_id))) {
return promise.set_error(Status::Error(3, "Not enough rights to change chat photo"));
@ -21428,7 +21426,7 @@ void MessagesManager::set_dialog_photo(DialogId dialog_id, const tl_object_ptr<t
break;
}
case DialogType::Channel: {
auto status = td_->contacts_manager_->get_channel_status(dialog_id.get_channel_id());
auto status = td_->contacts_manager_->get_channel_permissions(dialog_id.get_channel_id());
if (!status.can_change_info_and_settings()) {
return promise.set_error(Status::Error(3, "Not enough rights to change chat photo"));
}
@ -21499,7 +21497,7 @@ void MessagesManager::set_dialog_title(DialogId dialog_id, const string &title,
return promise.set_error(Status::Error(3, "Can't change private chat title"));
case DialogType::Chat: {
auto chat_id = dialog_id.get_chat_id();
auto status = td_->contacts_manager_->get_chat_status(chat_id);
auto status = td_->contacts_manager_->get_chat_permissions(chat_id);
if (!status.can_change_info_and_settings() ||
(td_->auth_manager_->is_bot() && !td_->contacts_manager_->is_appointed_chat_administrator(chat_id))) {
return promise.set_error(Status::Error(3, "Not enough rights to change chat title"));
@ -21507,7 +21505,7 @@ void MessagesManager::set_dialog_title(DialogId dialog_id, const string &title,
break;
}
case DialogType::Channel: {
auto status = td_->contacts_manager_->get_channel_status(dialog_id.get_channel_id());
auto status = td_->contacts_manager_->get_channel_permissions(dialog_id.get_channel_id());
if (!status.can_change_info_and_settings()) {
return promise.set_error(Status::Error(3, "Not enough rights to change chat title"));
}
@ -21551,7 +21549,7 @@ void MessagesManager::set_dialog_permissions(DialogId dialog_id,
return promise.set_error(Status::Error(3, "Can't change private chat permissions"));
case DialogType::Chat: {
auto chat_id = dialog_id.get_chat_id();
auto status = td_->contacts_manager_->get_chat_status(chat_id);
auto status = td_->contacts_manager_->get_chat_permissions(chat_id);
if (!status.can_restrict_members()) {
return promise.set_error(Status::Error(3, "Not enough rights to change chat permissions"));
}
@ -21561,7 +21559,7 @@ void MessagesManager::set_dialog_permissions(DialogId dialog_id,
if (is_broadcast_channel(dialog_id)) {
return promise.set_error(Status::Error(3, "Can't change channel chat permissions"));
}
auto status = td_->contacts_manager_->get_channel_status(dialog_id.get_channel_id());
auto status = td_->contacts_manager_->get_channel_permissions(dialog_id.get_channel_id());
if (!status.can_restrict_members()) {
return promise.set_error(Status::Error(3, "Not enough rights to change chat permissions"));
}
@ -21624,7 +21622,7 @@ void MessagesManager::pin_dialog_message(DialogId dialog_id, MessageId message_i
break;
case DialogType::Chat: {
auto chat_id = dialog_id.get_chat_id();
auto status = td_->contacts_manager_->get_chat_status(chat_id);
auto status = td_->contacts_manager_->get_chat_permissions(chat_id);
if (!status.can_pin_messages() ||
(td_->auth_manager_->is_bot() && !td_->contacts_manager_->is_appointed_chat_administrator(chat_id))) {
return promise.set_error(Status::Error(3, PSLICE() << "Not enough rights to " << action << " a message"));
@ -21632,7 +21630,7 @@ void MessagesManager::pin_dialog_message(DialogId dialog_id, MessageId message_i
break;
}
case DialogType::Channel: {
auto status = td_->contacts_manager_->get_channel_status(dialog_id.get_channel_id());
auto status = td_->contacts_manager_->get_channel_permissions(dialog_id.get_channel_id());
bool can_pin = is_broadcast_channel(dialog_id) ? status.can_edit_messages() : status.can_pin_messages();
if (!can_pin) {
return promise.set_error(Status::Error(6, PSLICE() << "Not enough rights to " << action << " a message"));
@ -24496,8 +24494,7 @@ void MessagesManager::update_dialog_pos(Dialog *d, bool remove_from_dialog_list,
}
case DialogType::Channel: {
auto channel_id = d->dialog_id.get_channel_id();
auto status = td_->contacts_manager_->get_channel_status(channel_id);
if (!status.is_member()) {
if (!td_->contacts_manager_->get_channel_status(channel_id).is_member()) {
remove_from_dialog_list = true;
}
break;