1 //
2 // Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 #include "td/telegram/DialogParticipant.h"
8
9 #include "td/telegram/ContactsManager.h"
10 #include "td/telegram/Global.h"
11 #include "td/telegram/misc.h"
12 #include "td/telegram/Td.h"
13
14 #include "td/utils/common.h"
15 #include "td/utils/logging.h"
16
17 #include <limits>
18
19 namespace td {
20
DialogParticipantStatus(Type type,uint32 flags,int32 until_date,string rank)21 DialogParticipantStatus::DialogParticipantStatus(Type type, uint32 flags, int32 until_date, string rank)
22 : type_(type), flags_(flags), until_date_(until_date), rank_(strip_empty_characters(std::move(rank), 16)) {
23 }
24
fix_until_date(int32 date)25 int32 DialogParticipantStatus::fix_until_date(int32 date) {
26 if (date == std::numeric_limits<int32>::max() || date < 0) {
27 return 0;
28 }
29 return date;
30 }
31
Creator(bool is_member,bool is_anonymous,string rank)32 DialogParticipantStatus DialogParticipantStatus::Creator(bool is_member, bool is_anonymous, string rank) {
33 return DialogParticipantStatus(Type::Creator,
34 ALL_ADMINISTRATOR_RIGHTS | ALL_PERMISSION_RIGHTS | (is_member ? IS_MEMBER : 0) |
35 (is_anonymous ? IS_ANONYMOUS : 0),
36 0, std::move(rank));
37 }
38
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)39 DialogParticipantStatus DialogParticipantStatus::Administrator(bool is_anonymous, string rank, bool can_be_edited,
40 bool can_manage_dialog, bool can_change_info,
41 bool can_post_messages, bool can_edit_messages,
42 bool can_delete_messages, bool can_invite_users,
43 bool can_restrict_members, bool can_pin_messages,
44 bool can_promote_members, bool can_manage_calls) {
45 uint32 flags = (static_cast<uint32>(can_be_edited) * CAN_BE_EDITED) |
46 (static_cast<uint32>(can_manage_dialog) * CAN_MANAGE_DIALOG) |
47 (static_cast<uint32>(can_change_info) * CAN_CHANGE_INFO_AND_SETTINGS_ADMIN) |
48 (static_cast<uint32>(can_post_messages) * CAN_POST_MESSAGES) |
49 (static_cast<uint32>(can_edit_messages) * CAN_EDIT_MESSAGES) |
50 (static_cast<uint32>(can_delete_messages) * CAN_DELETE_MESSAGES) |
51 (static_cast<uint32>(can_invite_users) * CAN_INVITE_USERS_ADMIN) |
52 (static_cast<uint32>(can_restrict_members) * CAN_RESTRICT_MEMBERS) |
53 (static_cast<uint32>(can_pin_messages) * CAN_PIN_MESSAGES_ADMIN) |
54 (static_cast<uint32>(can_promote_members) * CAN_PROMOTE_MEMBERS) |
55 (static_cast<uint32>(can_manage_calls) * CAN_MANAGE_CALLS) |
56 (static_cast<uint32>(is_anonymous) * IS_ANONYMOUS);
57 if (flags == 0 || flags == CAN_BE_EDITED) {
58 return Member();
59 }
60 flags |= CAN_MANAGE_DIALOG;
61 return DialogParticipantStatus(Type::Administrator, IS_MEMBER | ALL_RESTRICTED_RIGHTS | flags, 0, std::move(rank));
62 }
63
Member()64 DialogParticipantStatus DialogParticipantStatus::Member() {
65 return DialogParticipantStatus(Type::Member, IS_MEMBER | ALL_PERMISSION_RIGHTS, 0, string());
66 }
67
Restricted(bool is_member,int32 restricted_until_date,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)68 DialogParticipantStatus DialogParticipantStatus::Restricted(
69 bool is_member, int32 restricted_until_date, bool can_send_messages, bool can_send_media, bool can_send_stickers,
70 bool can_send_animations, bool can_send_games, bool can_use_inline_bots, bool can_add_web_page_previews,
71 bool can_send_polls, bool can_change_info_and_settings, bool can_invite_users, bool can_pin_messages) {
72 uint32 flags = (static_cast<uint32>(can_send_messages) * CAN_SEND_MESSAGES) |
73 (static_cast<uint32>(can_send_media) * CAN_SEND_MEDIA) |
74 (static_cast<uint32>(can_send_stickers) * CAN_SEND_STICKERS) |
75 (static_cast<uint32>(can_send_animations) * CAN_SEND_ANIMATIONS) |
76 (static_cast<uint32>(can_send_games) * CAN_SEND_GAMES) |
77 (static_cast<uint32>(can_use_inline_bots) * CAN_USE_INLINE_BOTS) |
78 (static_cast<uint32>(can_add_web_page_previews) * CAN_ADD_WEB_PAGE_PREVIEWS) |
79 (static_cast<uint32>(can_send_polls) * CAN_SEND_POLLS) |
80 (static_cast<uint32>(can_change_info_and_settings) * CAN_CHANGE_INFO_AND_SETTINGS_BANNED) |
81 (static_cast<uint32>(can_invite_users) * CAN_INVITE_USERS_BANNED) |
82 (static_cast<uint32>(can_pin_messages) * CAN_PIN_MESSAGES_BANNED) |
83 (static_cast<uint32>(is_member) * IS_MEMBER);
84 if (flags == (IS_MEMBER | ALL_PERMISSION_RIGHTS)) {
85 return Member();
86 }
87 return DialogParticipantStatus(Type::Restricted, flags, fix_until_date(restricted_until_date), string());
88 }
89
Left()90 DialogParticipantStatus DialogParticipantStatus::Left() {
91 return DialogParticipantStatus(Type::Left, ALL_PERMISSION_RIGHTS, 0, string());
92 }
93
Banned(int32 banned_until_date)94 DialogParticipantStatus DialogParticipantStatus::Banned(int32 banned_until_date) {
95 return DialogParticipantStatus(Type::Banned, 0, fix_until_date(banned_until_date), string());
96 }
97
GroupAdministrator(bool is_creator)98 DialogParticipantStatus DialogParticipantStatus::GroupAdministrator(bool is_creator) {
99 return Administrator(false, string(), is_creator, true, true, false, false, true, true, true, true, false, true);
100 }
101
ChannelAdministrator(bool is_creator,bool is_megagroup)102 DialogParticipantStatus DialogParticipantStatus::ChannelAdministrator(bool is_creator, bool is_megagroup) {
103 if (is_megagroup) {
104 return Administrator(false, string(), is_creator, true, true, false, false, true, true, true, true, false, false);
105 } else {
106 return Administrator(false, string(), is_creator, true, false, true, true, true, false, true, false, false, false);
107 }
108 }
109
get_restricted_rights() const110 RestrictedRights DialogParticipantStatus::get_restricted_rights() const {
111 return RestrictedRights(can_send_messages(), can_send_media(), can_send_stickers(), can_send_animations(),
112 can_send_games(), can_use_inline_bots(), can_add_web_page_previews(), can_send_polls(),
113 can_change_info_and_settings(), can_invite_users(), can_pin_messages());
114 }
115
get_chat_member_status_object() const116 tl_object_ptr<td_api::ChatMemberStatus> DialogParticipantStatus::get_chat_member_status_object() const {
117 switch (type_) {
118 case Type::Creator:
119 return td_api::make_object<td_api::chatMemberStatusCreator>(rank_, is_anonymous(), is_member());
120 case Type::Administrator:
121 return td_api::make_object<td_api::chatMemberStatusAdministrator>(
122 rank_, can_be_edited(), can_manage_dialog(), can_change_info_and_settings(), can_post_messages(),
123 can_edit_messages(), can_delete_messages(), can_invite_users(), can_restrict_members(), can_pin_messages(),
124 can_promote_members(), can_manage_calls(), is_anonymous());
125 case Type::Member:
126 return td_api::make_object<td_api::chatMemberStatusMember>();
127 case Type::Restricted:
128 return td_api::make_object<td_api::chatMemberStatusRestricted>(
129 is_member(), until_date_, get_restricted_rights().get_chat_permissions_object());
130 case Type::Left:
131 return td_api::make_object<td_api::chatMemberStatusLeft>();
132 case Type::Banned:
133 return td_api::make_object<td_api::chatMemberStatusBanned>(until_date_);
134 default:
135 UNREACHABLE();
136 return nullptr;
137 }
138 }
139
get_chat_admin_rights() const140 tl_object_ptr<telegram_api::chatAdminRights> DialogParticipantStatus::get_chat_admin_rights() const {
141 int32 flags = 0;
142 if ((flags_ & CAN_CHANGE_INFO_AND_SETTINGS_ADMIN) != 0) {
143 flags |= telegram_api::chatAdminRights::CHANGE_INFO_MASK;
144 }
145 if (can_post_messages()) {
146 flags |= telegram_api::chatAdminRights::POST_MESSAGES_MASK;
147 }
148 if (can_edit_messages()) {
149 flags |= telegram_api::chatAdminRights::EDIT_MESSAGES_MASK;
150 }
151 if (can_delete_messages()) {
152 flags |= telegram_api::chatAdminRights::DELETE_MESSAGES_MASK;
153 }
154 if ((flags_ & CAN_INVITE_USERS_ADMIN) != 0) {
155 flags |= telegram_api::chatAdminRights::INVITE_USERS_MASK;
156 }
157 if (can_restrict_members()) {
158 flags |= telegram_api::chatAdminRights::BAN_USERS_MASK;
159 }
160 if ((flags_ & CAN_PIN_MESSAGES_ADMIN) != 0) {
161 flags |= telegram_api::chatAdminRights::PIN_MESSAGES_MASK;
162 }
163 if (can_promote_members()) {
164 flags |= telegram_api::chatAdminRights::ADD_ADMINS_MASK;
165 }
166 if (can_manage_calls()) {
167 flags |= telegram_api::chatAdminRights::MANAGE_CALL_MASK;
168 }
169 if (is_anonymous()) {
170 flags |= telegram_api::chatAdminRights::ANONYMOUS_MASK;
171 }
172 if (can_manage_dialog()) {
173 flags |= telegram_api::chatAdminRights::OTHER_MASK;
174 }
175
176 LOG(INFO) << "Create chat admin rights " << flags;
177 return make_tl_object<telegram_api::chatAdminRights>(
178 flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/,
179 false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/);
180 }
181
get_chat_banned_rights() const182 tl_object_ptr<telegram_api::chatBannedRights> DialogParticipantStatus::get_chat_banned_rights() const {
183 int32 flags = 0;
184 if (type_ == Type::Banned) {
185 flags |= telegram_api::chatBannedRights::VIEW_MESSAGES_MASK;
186 }
187 if (!can_send_messages()) {
188 flags |= telegram_api::chatBannedRights::SEND_MESSAGES_MASK;
189 }
190 if (!can_send_media()) {
191 flags |= telegram_api::chatBannedRights::SEND_MEDIA_MASK;
192 }
193 if (!can_send_stickers()) {
194 flags |= telegram_api::chatBannedRights::SEND_STICKERS_MASK;
195 }
196 if (!can_send_animations()) {
197 flags |= telegram_api::chatBannedRights::SEND_GIFS_MASK;
198 }
199 if (!can_send_games()) {
200 flags |= telegram_api::chatBannedRights::SEND_GAMES_MASK;
201 }
202 if (!can_use_inline_bots()) {
203 flags |= telegram_api::chatBannedRights::SEND_INLINE_MASK;
204 }
205 if (!can_add_web_page_previews()) {
206 flags |= telegram_api::chatBannedRights::EMBED_LINKS_MASK;
207 }
208 if (!can_send_polls()) {
209 flags |= telegram_api::chatBannedRights::SEND_POLLS_MASK;
210 }
211 if ((flags_ & CAN_CHANGE_INFO_AND_SETTINGS_BANNED) == 0) {
212 flags |= telegram_api::chatBannedRights::CHANGE_INFO_MASK;
213 }
214 if ((flags_ & CAN_INVITE_USERS_BANNED) == 0) {
215 flags |= telegram_api::chatBannedRights::INVITE_USERS_MASK;
216 }
217 if ((flags_ & CAN_PIN_MESSAGES_BANNED) == 0) {
218 flags |= telegram_api::chatBannedRights::PIN_MESSAGES_MASK;
219 }
220
221 LOG(INFO) << "Create chat banned rights " << flags << " until " << until_date_;
222 return make_tl_object<telegram_api::chatBannedRights>(
223 flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/,
224 false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/,
225 false /*ignored*/, until_date_);
226 }
227
apply_restrictions(RestrictedRights default_restrictions,bool is_bot) const228 DialogParticipantStatus DialogParticipantStatus::apply_restrictions(RestrictedRights default_restrictions,
229 bool is_bot) const {
230 auto flags = flags_;
231 switch (type_) {
232 case Type::Creator:
233 // creator can do anything and isn't affected by restrictions
234 break;
235 case Type::Administrator:
236 // administrators aren't affected by restrictions, but if everyone can invite users,
237 // pin messages or change info, they also can do that
238 if (!is_bot) {
239 flags |= default_restrictions.flags_ & ALL_ADMIN_PERMISSION_RIGHTS;
240 }
241 break;
242 case Type::Member:
243 case Type::Restricted:
244 case Type::Left:
245 // members and restricted are affected by default restrictions
246 flags &= ~ALL_PERMISSION_RIGHTS | default_restrictions.flags_;
247 if (is_bot) {
248 flags &= ~ALL_ADMIN_PERMISSION_RIGHTS;
249 }
250 break;
251 case Type::Banned:
252 // banned can do nothing, even restrictions allows them to do that
253 break;
254 default:
255 UNREACHABLE();
256 break;
257 }
258
259 return DialogParticipantStatus(type_, flags, 0, string());
260 }
261
update_restrictions() const262 void DialogParticipantStatus::update_restrictions() const {
263 if (until_date_ != 0 && G()->unix_time() > until_date_) {
264 until_date_ = 0;
265 if (type_ == Type::Restricted) {
266 if (is_member()) {
267 type_ = Type::Member;
268 } else {
269 type_ = Type::Left;
270 }
271 flags_ |= ALL_PERMISSION_RIGHTS;
272 } else if (type_ == Type::Banned) {
273 type_ = Type::Left;
274 } else {
275 UNREACHABLE();
276 }
277 }
278 }
279
operator ==(const DialogParticipantStatus & lhs,const DialogParticipantStatus & rhs)280 bool operator==(const DialogParticipantStatus &lhs, const DialogParticipantStatus &rhs) {
281 return lhs.type_ == rhs.type_ && lhs.flags_ == rhs.flags_ && lhs.until_date_ == rhs.until_date_ &&
282 lhs.rank_ == rhs.rank_;
283 }
284
operator !=(const DialogParticipantStatus & lhs,const DialogParticipantStatus & rhs)285 bool operator!=(const DialogParticipantStatus &lhs, const DialogParticipantStatus &rhs) {
286 return !(lhs == rhs);
287 }
288
operator <<(StringBuilder & string_builder,const DialogParticipantStatus & status)289 StringBuilder &operator<<(StringBuilder &string_builder, const DialogParticipantStatus &status) {
290 switch (status.type_) {
291 case DialogParticipantStatus::Type::Creator:
292 string_builder << "Creator";
293 if (!status.is_member()) {
294 string_builder << "-non-member";
295 }
296 if (!status.rank_.empty()) {
297 string_builder << " [" << status.rank_ << "]";
298 }
299 if (status.is_anonymous()) {
300 string_builder << "-anonymous";
301 }
302 return string_builder;
303 case DialogParticipantStatus::Type::Administrator:
304 string_builder << "Administrator: ";
305 if (status.can_manage_dialog()) {
306 string_builder << "(manage)";
307 }
308 if (status.can_change_info_and_settings()) {
309 string_builder << "(change)";
310 }
311 if (status.can_post_messages()) {
312 string_builder << "(post)";
313 }
314 if (status.can_edit_messages()) {
315 string_builder << "(edit)";
316 }
317 if (status.can_delete_messages()) {
318 string_builder << "(delete)";
319 }
320 if (status.can_invite_users()) {
321 string_builder << "(invite)";
322 }
323 if (status.can_restrict_members()) {
324 string_builder << "(restrict)";
325 }
326 if (status.can_pin_messages()) {
327 string_builder << "(pin)";
328 }
329 if (status.can_promote_members()) {
330 string_builder << "(promote)";
331 }
332 if (status.can_manage_calls()) {
333 string_builder << "(voice chat)";
334 }
335 if (!status.rank_.empty()) {
336 string_builder << " [" << status.rank_ << "]";
337 }
338 if (status.is_anonymous()) {
339 string_builder << "-anonymous";
340 }
341 return string_builder;
342 case DialogParticipantStatus::Type::Member:
343 return string_builder << "Member";
344 case DialogParticipantStatus::Type::Restricted:
345 string_builder << "Restricted ";
346 if (status.until_date_ == 0) {
347 string_builder << "forever ";
348 } else {
349 string_builder << "until " << status.until_date_ << " ";
350 }
351 if (!status.is_member()) {
352 string_builder << "non-";
353 }
354 string_builder << "member: ";
355 if (!status.can_send_messages()) {
356 string_builder << "(text)";
357 }
358 if (!status.can_send_media()) {
359 string_builder << "(media)";
360 }
361 if (!status.can_send_stickers()) {
362 string_builder << "(stickers)";
363 }
364 if (!status.can_send_animations()) {
365 string_builder << "(animations)";
366 }
367 if (!status.can_send_games()) {
368 string_builder << "(games)";
369 }
370 if (!status.can_send_polls()) {
371 string_builder << "(polls)";
372 }
373 if (!status.can_use_inline_bots()) {
374 string_builder << "(inline bots)";
375 }
376 if (!status.can_add_web_page_previews()) {
377 string_builder << "(links)";
378 }
379 if (!status.can_change_info_and_settings()) {
380 string_builder << "(change)";
381 }
382 if (!status.can_invite_users()) {
383 string_builder << "(invite)";
384 }
385 if (!status.can_pin_messages()) {
386 string_builder << "(pin)";
387 }
388 return string_builder;
389 case DialogParticipantStatus::Type::Left:
390 return string_builder << "Left";
391 case DialogParticipantStatus::Type::Banned:
392 string_builder << "Banned ";
393 if (status.until_date_ == 0) {
394 string_builder << "forever";
395 } else {
396 string_builder << "until " << status.until_date_;
397 }
398 return string_builder;
399 default:
400 UNREACHABLE();
401 return string_builder << "Impossible";
402 }
403 }
404
get_dialog_participant_status(const tl_object_ptr<td_api::ChatMemberStatus> & status)405 DialogParticipantStatus get_dialog_participant_status(const tl_object_ptr<td_api::ChatMemberStatus> &status) {
406 auto constructor_id = status == nullptr ? td_api::chatMemberStatusMember::ID : status->get_id();
407 switch (constructor_id) {
408 case td_api::chatMemberStatusCreator::ID: {
409 auto st = static_cast<const td_api::chatMemberStatusCreator *>(status.get());
410 auto custom_title = st->custom_title_;
411 if (!clean_input_string(custom_title)) {
412 custom_title.clear();
413 }
414 return DialogParticipantStatus::Creator(st->is_member_, st->is_anonymous_, custom_title);
415 }
416 case td_api::chatMemberStatusAdministrator::ID: {
417 auto st = static_cast<const td_api::chatMemberStatusAdministrator *>(status.get());
418 auto custom_title = st->custom_title_;
419 if (!clean_input_string(custom_title)) {
420 custom_title.clear();
421 }
422 return DialogParticipantStatus::Administrator(
423 st->is_anonymous_, custom_title, true /*st->can_be_edited_*/, st->can_manage_chat_, st->can_change_info_,
424 st->can_post_messages_, st->can_edit_messages_, st->can_delete_messages_, st->can_invite_users_,
425 st->can_restrict_members_, st->can_pin_messages_, st->can_promote_members_, st->can_manage_video_chats_);
426 }
427 case td_api::chatMemberStatusMember::ID:
428 return DialogParticipantStatus::Member();
429 case td_api::chatMemberStatusRestricted::ID: {
430 auto st = static_cast<const td_api::chatMemberStatusRestricted *>(status.get());
431 auto permissions = st->permissions_.get();
432 if (permissions == nullptr) {
433 return DialogParticipantStatus::Restricted(st->is_member_, st->restricted_until_date_, false, false, false,
434 false, false, false, false, false, false, false, false);
435 }
436 bool can_send_polls = permissions->can_send_polls_;
437 bool can_send_media = permissions->can_send_media_messages_;
438 bool can_send_messages = permissions->can_send_messages_ || can_send_media || can_send_polls ||
439 permissions->can_send_other_messages_ || permissions->can_add_web_page_previews_;
440 return DialogParticipantStatus::Restricted(
441 st->is_member_, st->restricted_until_date_, can_send_messages, can_send_media,
442 permissions->can_send_other_messages_, permissions->can_send_other_messages_,
443 permissions->can_send_other_messages_, permissions->can_send_other_messages_,
444 permissions->can_add_web_page_previews_, permissions->can_send_polls_, permissions->can_change_info_,
445 permissions->can_invite_users_, permissions->can_pin_messages_);
446 }
447 case td_api::chatMemberStatusLeft::ID:
448 return DialogParticipantStatus::Left();
449 case td_api::chatMemberStatusBanned::ID: {
450 auto st = static_cast<const td_api::chatMemberStatusBanned *>(status.get());
451 return DialogParticipantStatus::Banned(st->banned_until_date_);
452 }
453 default:
454 UNREACHABLE();
455 return DialogParticipantStatus::Member();
456 }
457 }
458
get_dialog_participant_status(bool can_be_edited,tl_object_ptr<telegram_api::chatAdminRights> && admin_rights,string rank)459 DialogParticipantStatus get_dialog_participant_status(bool can_be_edited,
460 tl_object_ptr<telegram_api::chatAdminRights> &&admin_rights,
461 string rank) {
462 bool can_change_info = (admin_rights->flags_ & telegram_api::chatAdminRights::CHANGE_INFO_MASK) != 0;
463 bool can_post_messages = (admin_rights->flags_ & telegram_api::chatAdminRights::POST_MESSAGES_MASK) != 0;
464 bool can_edit_messages = (admin_rights->flags_ & telegram_api::chatAdminRights::EDIT_MESSAGES_MASK) != 0;
465 bool can_delete_messages = (admin_rights->flags_ & telegram_api::chatAdminRights::DELETE_MESSAGES_MASK) != 0;
466 bool can_invite_users = (admin_rights->flags_ & telegram_api::chatAdminRights::INVITE_USERS_MASK) != 0;
467 bool can_restrict_members = (admin_rights->flags_ & telegram_api::chatAdminRights::BAN_USERS_MASK) != 0;
468 bool can_pin_messages = (admin_rights->flags_ & telegram_api::chatAdminRights::PIN_MESSAGES_MASK) != 0;
469 bool can_promote_members = (admin_rights->flags_ & telegram_api::chatAdminRights::ADD_ADMINS_MASK) != 0;
470 bool can_manage_calls = (admin_rights->flags_ & telegram_api::chatAdminRights::MANAGE_CALL_MASK) != 0;
471 bool is_anonymous = (admin_rights->flags_ & telegram_api::chatAdminRights::ANONYMOUS_MASK) != 0;
472 bool can_manage_dialog = (admin_rights->flags_ & telegram_api::chatAdminRights::OTHER_MASK) != 0;
473 if (!can_manage_dialog) {
474 LOG(ERROR) << "Receive wrong other flag in " << to_string(admin_rights);
475 }
476 return DialogParticipantStatus::Administrator(is_anonymous, std::move(rank), can_be_edited, can_manage_dialog,
477 can_change_info, can_post_messages, can_edit_messages,
478 can_delete_messages, can_invite_users, can_restrict_members,
479 can_pin_messages, can_promote_members, can_manage_calls);
480 }
481
get_dialog_participant_status(bool is_member,tl_object_ptr<telegram_api::chatBannedRights> && banned_rights)482 DialogParticipantStatus get_dialog_participant_status(bool is_member,
483 tl_object_ptr<telegram_api::chatBannedRights> &&banned_rights) {
484 bool can_view_messages = (banned_rights->flags_ & telegram_api::chatBannedRights::VIEW_MESSAGES_MASK) == 0;
485 if (!can_view_messages) {
486 return DialogParticipantStatus::Banned(banned_rights->until_date_);
487 }
488 bool can_send_messages = (banned_rights->flags_ & telegram_api::chatBannedRights::SEND_MESSAGES_MASK) == 0;
489 bool can_send_media_messages = (banned_rights->flags_ & telegram_api::chatBannedRights::SEND_MEDIA_MASK) == 0;
490 bool can_send_stickers = (banned_rights->flags_ & telegram_api::chatBannedRights::SEND_STICKERS_MASK) == 0;
491 bool can_send_animations = (banned_rights->flags_ & telegram_api::chatBannedRights::SEND_GIFS_MASK) == 0;
492 bool can_send_games = (banned_rights->flags_ & telegram_api::chatBannedRights::SEND_GAMES_MASK) == 0;
493 bool can_use_inline_bots = (banned_rights->flags_ & telegram_api::chatBannedRights::SEND_INLINE_MASK) == 0;
494 bool can_add_web_page_previews = (banned_rights->flags_ & telegram_api::chatBannedRights::EMBED_LINKS_MASK) == 0;
495 bool can_send_polls = (banned_rights->flags_ & telegram_api::chatBannedRights::SEND_POLLS_MASK) == 0;
496 bool can_change_info_and_settings = (banned_rights->flags_ & telegram_api::chatBannedRights::CHANGE_INFO_MASK) == 0;
497 bool can_invite_users = (banned_rights->flags_ & telegram_api::chatBannedRights::INVITE_USERS_MASK) == 0;
498 bool can_pin_messages = (banned_rights->flags_ & telegram_api::chatBannedRights::PIN_MESSAGES_MASK) == 0;
499 return DialogParticipantStatus::Restricted(
500 is_member, banned_rights->until_date_, can_send_messages, can_send_media_messages, can_send_stickers,
501 can_send_animations, can_send_games, can_use_inline_bots, can_add_web_page_previews, can_send_polls,
502 can_change_info_and_settings, can_invite_users, can_pin_messages);
503 }
504
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)505 RestrictedRights::RestrictedRights(bool can_send_messages, bool can_send_media, bool can_send_stickers,
506 bool can_send_animations, bool can_send_games, bool can_use_inline_bots,
507 bool can_add_web_page_previews, bool can_send_polls,
508 bool can_change_info_and_settings, bool can_invite_users, bool can_pin_messages) {
509 flags_ = (static_cast<uint32>(can_send_messages) * CAN_SEND_MESSAGES) |
510 (static_cast<uint32>(can_send_media) * CAN_SEND_MEDIA) |
511 (static_cast<uint32>(can_send_stickers) * CAN_SEND_STICKERS) |
512 (static_cast<uint32>(can_send_animations) * CAN_SEND_ANIMATIONS) |
513 (static_cast<uint32>(can_send_games) * CAN_SEND_GAMES) |
514 (static_cast<uint32>(can_use_inline_bots) * CAN_USE_INLINE_BOTS) |
515 (static_cast<uint32>(can_add_web_page_previews) * CAN_ADD_WEB_PAGE_PREVIEWS) |
516 (static_cast<uint32>(can_send_polls) * CAN_SEND_POLLS) |
517 (static_cast<uint32>(can_change_info_and_settings) * CAN_CHANGE_INFO_AND_SETTINGS) |
518 (static_cast<uint32>(can_invite_users) * CAN_INVITE_USERS) |
519 (static_cast<uint32>(can_pin_messages) * CAN_PIN_MESSAGES);
520 }
521
get_chat_permissions_object() const522 tl_object_ptr<td_api::chatPermissions> RestrictedRights::get_chat_permissions_object() const {
523 return td_api::make_object<td_api::chatPermissions>(
524 can_send_messages(), can_send_media(), can_send_polls(),
525 can_send_stickers() || can_send_animations() || can_send_games() || can_use_inline_bots(),
526 can_add_web_page_previews(), can_change_info_and_settings(), can_invite_users(), can_pin_messages());
527 }
528
get_chat_banned_rights() const529 tl_object_ptr<telegram_api::chatBannedRights> RestrictedRights::get_chat_banned_rights() const {
530 int32 flags = 0;
531 if (!can_send_messages()) {
532 flags |= telegram_api::chatBannedRights::SEND_MESSAGES_MASK;
533 }
534 if (!can_send_media()) {
535 flags |= telegram_api::chatBannedRights::SEND_MEDIA_MASK;
536 }
537 if (!can_send_stickers()) {
538 flags |= telegram_api::chatBannedRights::SEND_STICKERS_MASK;
539 }
540 if (!can_send_animations()) {
541 flags |= telegram_api::chatBannedRights::SEND_GIFS_MASK;
542 }
543 if (!can_send_games()) {
544 flags |= telegram_api::chatBannedRights::SEND_GAMES_MASK;
545 }
546 if (!can_use_inline_bots()) {
547 flags |= telegram_api::chatBannedRights::SEND_INLINE_MASK;
548 }
549 if (!can_add_web_page_previews()) {
550 flags |= telegram_api::chatBannedRights::EMBED_LINKS_MASK;
551 }
552 if (!can_send_polls()) {
553 flags |= telegram_api::chatBannedRights::SEND_POLLS_MASK;
554 }
555 if (!can_change_info_and_settings()) {
556 flags |= telegram_api::chatBannedRights::CHANGE_INFO_MASK;
557 }
558 if (!can_invite_users()) {
559 flags |= telegram_api::chatBannedRights::INVITE_USERS_MASK;
560 }
561 if (!can_pin_messages()) {
562 flags |= telegram_api::chatBannedRights::PIN_MESSAGES_MASK;
563 }
564
565 LOG(INFO) << "Create chat banned rights " << flags;
566 return make_tl_object<telegram_api::chatBannedRights>(flags, false /*ignored*/, false /*ignored*/, false /*ignored*/,
567 false /*ignored*/, false /*ignored*/, false /*ignored*/,
568 false /*ignored*/, false /*ignored*/, false /*ignored*/,
569 false /*ignored*/, false /*ignored*/, false /*ignored*/, 0);
570 }
571
operator ==(const RestrictedRights & lhs,const RestrictedRights & rhs)572 bool operator==(const RestrictedRights &lhs, const RestrictedRights &rhs) {
573 return lhs.flags_ == rhs.flags_;
574 }
575
operator !=(const RestrictedRights & lhs,const RestrictedRights & rhs)576 bool operator!=(const RestrictedRights &lhs, const RestrictedRights &rhs) {
577 return !(lhs == rhs);
578 }
579
operator <<(StringBuilder & string_builder,const RestrictedRights & status)580 StringBuilder &operator<<(StringBuilder &string_builder, const RestrictedRights &status) {
581 string_builder << "Restricted: ";
582 if (!status.can_send_messages()) {
583 string_builder << "(text)";
584 }
585 if (!status.can_send_media()) {
586 string_builder << "(media)";
587 }
588 if (!status.can_send_stickers()) {
589 string_builder << "(stickers)";
590 }
591 if (!status.can_send_animations()) {
592 string_builder << "(animations)";
593 }
594 if (!status.can_send_games()) {
595 string_builder << "(games)";
596 }
597 if (!status.can_send_polls()) {
598 string_builder << "(polls)";
599 }
600 if (!status.can_use_inline_bots()) {
601 string_builder << "(inline bots)";
602 }
603 if (!status.can_add_web_page_previews()) {
604 string_builder << "(links)";
605 }
606 if (!status.can_change_info_and_settings()) {
607 string_builder << "(change)";
608 }
609 if (!status.can_invite_users()) {
610 string_builder << "(invite)";
611 }
612 if (!status.can_pin_messages()) {
613 string_builder << "(pin)";
614 }
615 return string_builder;
616 }
617
get_restricted_rights(tl_object_ptr<telegram_api::chatBannedRights> && banned_rights)618 RestrictedRights get_restricted_rights(tl_object_ptr<telegram_api::chatBannedRights> &&banned_rights) {
619 if (banned_rights == nullptr) {
620 return RestrictedRights(false, false, false, false, false, false, false, false, false, false, false);
621 }
622 bool can_view_messages = (banned_rights->flags_ & telegram_api::chatBannedRights::VIEW_MESSAGES_MASK) == 0;
623 if (!can_view_messages) {
624 LOG(ERROR) << "Can't view messages in restricted rights " << to_string(banned_rights);
625 }
626 LOG_IF(ERROR, banned_rights->until_date_ != std::numeric_limits<int32>::max())
627 << "Have until date " << banned_rights->until_date_ << " in restricted rights";
628
629 bool can_send_messages = (banned_rights->flags_ & telegram_api::chatBannedRights::SEND_MESSAGES_MASK) == 0;
630 bool can_send_media_messages = (banned_rights->flags_ & telegram_api::chatBannedRights::SEND_MEDIA_MASK) == 0;
631 bool can_send_stickers = (banned_rights->flags_ & telegram_api::chatBannedRights::SEND_STICKERS_MASK) == 0;
632 bool can_send_animations = (banned_rights->flags_ & telegram_api::chatBannedRights::SEND_GIFS_MASK) == 0;
633 bool can_send_games = (banned_rights->flags_ & telegram_api::chatBannedRights::SEND_GAMES_MASK) == 0;
634 bool can_use_inline_bots = (banned_rights->flags_ & telegram_api::chatBannedRights::SEND_INLINE_MASK) == 0;
635 bool can_add_web_page_previews = (banned_rights->flags_ & telegram_api::chatBannedRights::EMBED_LINKS_MASK) == 0;
636 bool can_send_polls = (banned_rights->flags_ & telegram_api::chatBannedRights::SEND_POLLS_MASK) == 0;
637 bool can_change_info_and_settings = (banned_rights->flags_ & telegram_api::chatBannedRights::CHANGE_INFO_MASK) == 0;
638 bool can_invite_users = (banned_rights->flags_ & telegram_api::chatBannedRights::INVITE_USERS_MASK) == 0;
639 bool can_pin_messages = (banned_rights->flags_ & telegram_api::chatBannedRights::PIN_MESSAGES_MASK) == 0;
640 return RestrictedRights(can_send_messages, can_send_media_messages, can_send_stickers, can_send_animations,
641 can_send_games, can_use_inline_bots, can_add_web_page_previews, can_send_polls,
642 can_change_info_and_settings, can_invite_users, can_pin_messages);
643 }
644
get_restricted_rights(const td_api::object_ptr<td_api::chatPermissions> & permissions)645 RestrictedRights get_restricted_rights(const td_api::object_ptr<td_api::chatPermissions> &permissions) {
646 bool can_send_polls = permissions->can_send_polls_;
647 bool can_send_media = permissions->can_send_media_messages_;
648 bool can_send_messages = permissions->can_send_messages_ || can_send_media || can_send_polls ||
649 permissions->can_send_other_messages_ || permissions->can_add_web_page_previews_;
650 return RestrictedRights(can_send_messages, can_send_media, permissions->can_send_other_messages_,
651 permissions->can_send_other_messages_, permissions->can_send_other_messages_,
652 permissions->can_send_other_messages_, permissions->can_add_web_page_previews_,
653 permissions->can_send_polls_, permissions->can_change_info_, permissions->can_invite_users_,
654 permissions->can_pin_messages_);
655 }
656
DialogParticipant(DialogId dialog_id,UserId inviter_user_id,int32 joined_date,DialogParticipantStatus status)657 DialogParticipant::DialogParticipant(DialogId dialog_id, UserId inviter_user_id, int32 joined_date,
658 DialogParticipantStatus status)
659 : dialog_id_(dialog_id), inviter_user_id_(inviter_user_id), joined_date_(joined_date), status_(std::move(status)) {
660 if (!inviter_user_id_.is_valid() && inviter_user_id_ != UserId()) {
661 LOG(ERROR) << "Receive inviter " << inviter_user_id_;
662 inviter_user_id_ = UserId();
663 }
664 if (joined_date_ < 0) {
665 LOG(ERROR) << "Receive date " << joined_date_;
666 joined_date_ = 0;
667 }
668 }
669
DialogParticipant(tl_object_ptr<telegram_api::ChatParticipant> && participant_ptr,int32 chat_creation_date,bool is_creator)670 DialogParticipant::DialogParticipant(tl_object_ptr<telegram_api::ChatParticipant> &&participant_ptr,
671 int32 chat_creation_date, bool is_creator) {
672 switch (participant_ptr->get_id()) {
673 case telegram_api::chatParticipant::ID: {
674 auto participant = move_tl_object_as<telegram_api::chatParticipant>(participant_ptr);
675 *this = {DialogId(UserId(participant->user_id_)), UserId(participant->inviter_id_), participant->date_,
676 DialogParticipantStatus::Member()};
677 break;
678 }
679 case telegram_api::chatParticipantCreator::ID: {
680 auto participant = move_tl_object_as<telegram_api::chatParticipantCreator>(participant_ptr);
681 *this = {DialogId(UserId(participant->user_id_)), UserId(participant->user_id_), chat_creation_date,
682 DialogParticipantStatus::Creator(true, false, string())};
683 break;
684 }
685 case telegram_api::chatParticipantAdmin::ID: {
686 auto participant = move_tl_object_as<telegram_api::chatParticipantAdmin>(participant_ptr);
687 *this = {DialogId(UserId(participant->user_id_)), UserId(participant->inviter_id_), participant->date_,
688 DialogParticipantStatus::GroupAdministrator(is_creator)};
689 break;
690 }
691 default:
692 UNREACHABLE();
693 }
694 }
695
DialogParticipant(tl_object_ptr<telegram_api::ChannelParticipant> && participant_ptr)696 DialogParticipant::DialogParticipant(tl_object_ptr<telegram_api::ChannelParticipant> &&participant_ptr) {
697 CHECK(participant_ptr != nullptr);
698
699 switch (participant_ptr->get_id()) {
700 case telegram_api::channelParticipant::ID: {
701 auto participant = move_tl_object_as<telegram_api::channelParticipant>(participant_ptr);
702 *this = {DialogId(UserId(participant->user_id_)), UserId(), participant->date_,
703 DialogParticipantStatus::Member()};
704 break;
705 }
706 case telegram_api::channelParticipantSelf::ID: {
707 auto participant = move_tl_object_as<telegram_api::channelParticipantSelf>(participant_ptr);
708 *this = {DialogId(UserId(participant->user_id_)), UserId(participant->inviter_id_), participant->date_,
709 DialogParticipantStatus::Member()};
710 break;
711 }
712 case telegram_api::channelParticipantCreator::ID: {
713 auto participant = move_tl_object_as<telegram_api::channelParticipantCreator>(participant_ptr);
714 *this = {DialogId(UserId(participant->user_id_)), UserId(), 0,
715 DialogParticipantStatus::Creator(true, participant->admin_rights_->anonymous_,
716 std::move(participant->rank_))};
717 break;
718 }
719 case telegram_api::channelParticipantAdmin::ID: {
720 auto participant = move_tl_object_as<telegram_api::channelParticipantAdmin>(participant_ptr);
721 *this = {DialogId(UserId(participant->user_id_)), UserId(participant->promoted_by_), participant->date_,
722 get_dialog_participant_status(participant->can_edit_, std::move(participant->admin_rights_),
723 std::move(participant->rank_))};
724 break;
725 }
726 case telegram_api::channelParticipantLeft::ID: {
727 auto participant = move_tl_object_as<telegram_api::channelParticipantLeft>(participant_ptr);
728 *this = {DialogId(participant->peer_), UserId(), 0, DialogParticipantStatus::Left()};
729 break;
730 }
731 case telegram_api::channelParticipantBanned::ID: {
732 auto participant = move_tl_object_as<telegram_api::channelParticipantBanned>(participant_ptr);
733 *this = {DialogId(participant->peer_), UserId(participant->kicked_by_), participant->date_,
734 get_dialog_participant_status(!participant->left_, std::move(participant->banned_rights_))};
735 break;
736 }
737 default:
738 UNREACHABLE();
739 break;
740 }
741 }
742
is_valid() const743 bool DialogParticipant::is_valid() const {
744 if (!dialog_id_.is_valid() || joined_date_ < 0) {
745 return false;
746 }
747 if (status_.is_restricted() || status_.is_banned() || (status_.is_administrator() && !status_.is_creator())) {
748 return inviter_user_id_.is_valid();
749 }
750 return true;
751 }
752
operator <<(StringBuilder & string_builder,const DialogParticipant & dialog_participant)753 StringBuilder &operator<<(StringBuilder &string_builder, const DialogParticipant &dialog_participant) {
754 return string_builder << '[' << dialog_participant.dialog_id_ << " invited by " << dialog_participant.inviter_user_id_
755 << " at " << dialog_participant.joined_date_ << " with status " << dialog_participant.status_
756 << ']';
757 }
758
get_chat_members_object(Td * td) const759 td_api::object_ptr<td_api::chatMembers> DialogParticipants::get_chat_members_object(Td *td) const {
760 vector<tl_object_ptr<td_api::chatMember>> chat_members;
761 chat_members.reserve(participants_.size());
762 for (auto &participant : participants_) {
763 chat_members.push_back(td->contacts_manager_->get_chat_member_object(participant));
764 }
765
766 return td_api::make_object<td_api::chatMembers>(total_count_, std::move(chat_members));
767 }
768
769 tl_object_ptr<telegram_api::ChannelParticipantsFilter>
get_input_channel_participants_filter() const770 ChannelParticipantsFilter::get_input_channel_participants_filter() const {
771 switch (type_) {
772 case Type::Recent:
773 return make_tl_object<telegram_api::channelParticipantsRecent>();
774 case Type::Contacts:
775 return make_tl_object<telegram_api::channelParticipantsContacts>(query_);
776 case Type::Administrators:
777 return make_tl_object<telegram_api::channelParticipantsAdmins>();
778 case Type::Search:
779 return make_tl_object<telegram_api::channelParticipantsSearch>(query_);
780 case Type::Mention: {
781 int32 flags = 0;
782 if (!query_.empty()) {
783 flags |= telegram_api::channelParticipantsMentions::Q_MASK;
784 }
785 if (top_thread_message_id_.is_valid()) {
786 flags |= telegram_api::channelParticipantsMentions::TOP_MSG_ID_MASK;
787 }
788 return make_tl_object<telegram_api::channelParticipantsMentions>(
789 flags, query_, top_thread_message_id_.get_server_message_id().get());
790 }
791 case Type::Restricted:
792 return make_tl_object<telegram_api::channelParticipantsBanned>(query_);
793 case Type::Banned:
794 return make_tl_object<telegram_api::channelParticipantsKicked>(query_);
795 case Type::Bots:
796 return make_tl_object<telegram_api::channelParticipantsBots>();
797 default:
798 UNREACHABLE();
799 return nullptr;
800 }
801 }
802
ChannelParticipantsFilter(const tl_object_ptr<td_api::SupergroupMembersFilter> & filter)803 ChannelParticipantsFilter::ChannelParticipantsFilter(const tl_object_ptr<td_api::SupergroupMembersFilter> &filter) {
804 if (filter == nullptr) {
805 type_ = Type::Recent;
806 return;
807 }
808 switch (filter->get_id()) {
809 case td_api::supergroupMembersFilterRecent::ID:
810 type_ = Type::Recent;
811 return;
812 case td_api::supergroupMembersFilterContacts::ID:
813 type_ = Type::Contacts;
814 query_ = static_cast<const td_api::supergroupMembersFilterContacts *>(filter.get())->query_;
815 return;
816 case td_api::supergroupMembersFilterAdministrators::ID:
817 type_ = Type::Administrators;
818 return;
819 case td_api::supergroupMembersFilterSearch::ID:
820 type_ = Type::Search;
821 query_ = static_cast<const td_api::supergroupMembersFilterSearch *>(filter.get())->query_;
822 return;
823 case td_api::supergroupMembersFilterMention::ID: {
824 auto mention_filter = static_cast<const td_api::supergroupMembersFilterMention *>(filter.get());
825 type_ = Type::Mention;
826 query_ = mention_filter->query_;
827 top_thread_message_id_ = MessageId(mention_filter->message_thread_id_);
828 if (!top_thread_message_id_.is_valid() || !top_thread_message_id_.is_server()) {
829 top_thread_message_id_ = MessageId();
830 }
831 return;
832 }
833 case td_api::supergroupMembersFilterRestricted::ID:
834 type_ = Type::Restricted;
835 query_ = static_cast<const td_api::supergroupMembersFilterRestricted *>(filter.get())->query_;
836 return;
837 case td_api::supergroupMembersFilterBanned::ID:
838 type_ = Type::Banned;
839 query_ = static_cast<const td_api::supergroupMembersFilterBanned *>(filter.get())->query_;
840 return;
841 case td_api::supergroupMembersFilterBots::ID:
842 type_ = Type::Bots;
843 return;
844 default:
845 UNREACHABLE();
846 type_ = Type::Recent;
847 }
848 }
849
operator <<(StringBuilder & string_builder,const ChannelParticipantsFilter & filter)850 StringBuilder &operator<<(StringBuilder &string_builder, const ChannelParticipantsFilter &filter) {
851 switch (filter.type_) {
852 case ChannelParticipantsFilter::Type::Recent:
853 return string_builder << "Recent";
854 case ChannelParticipantsFilter::Type::Contacts:
855 return string_builder << "Contacts \"" << filter.query_ << '"';
856 case ChannelParticipantsFilter::Type::Administrators:
857 return string_builder << "Administrators";
858 case ChannelParticipantsFilter::Type::Search:
859 return string_builder << "Search \"" << filter.query_ << '"';
860 case ChannelParticipantsFilter::Type::Mention:
861 return string_builder << "Mention \"" << filter.query_ << "\" in thread of " << filter.top_thread_message_id_;
862 case ChannelParticipantsFilter::Type::Restricted:
863 return string_builder << "Restricted \"" << filter.query_ << '"';
864 case ChannelParticipantsFilter::Type::Banned:
865 return string_builder << "Banned \"" << filter.query_ << '"';
866 case ChannelParticipantsFilter::Type::Bots:
867 return string_builder << "Bots";
868 default:
869 UNREACHABLE();
870 return string_builder;
871 }
872 }
873
operator <<(StringBuilder & string_builder,const DialogParticipantsFilter & filter)874 StringBuilder &operator<<(StringBuilder &string_builder, const DialogParticipantsFilter &filter) {
875 switch (filter.type_) {
876 case DialogParticipantsFilter::Type::Contacts:
877 return string_builder << "Contacts";
878 case DialogParticipantsFilter::Type::Administrators:
879 return string_builder << "Administrators";
880 case DialogParticipantsFilter::Type::Members:
881 return string_builder << "Members";
882 case DialogParticipantsFilter::Type::Restricted:
883 return string_builder << "Restricted";
884 case DialogParticipantsFilter::Type::Banned:
885 return string_builder << "Banned";
886 case DialogParticipantsFilter::Type::Mention:
887 return string_builder << "Mention";
888 case DialogParticipantsFilter::Type::Bots:
889 return string_builder << "Bots";
890 default:
891 UNREACHABLE();
892 return string_builder;
893 }
894 }
895
DialogParticipantsFilter(const tl_object_ptr<td_api::ChatMembersFilter> & filter)896 DialogParticipantsFilter::DialogParticipantsFilter(const tl_object_ptr<td_api::ChatMembersFilter> &filter) {
897 if (filter == nullptr) {
898 type_ = Type::Members;
899 return;
900 }
901 switch (filter->get_id()) {
902 case td_api::chatMembersFilterContacts::ID:
903 type_ = Type::Contacts;
904 break;
905 case td_api::chatMembersFilterAdministrators::ID:
906 type_ = Type::Administrators;
907 break;
908 case td_api::chatMembersFilterMembers::ID:
909 type_ = Type::Members;
910 break;
911 case td_api::chatMembersFilterRestricted::ID:
912 type_ = Type::Restricted;
913 break;
914 case td_api::chatMembersFilterBanned::ID:
915 type_ = Type::Banned;
916 break;
917 case td_api::chatMembersFilterMention::ID: {
918 auto mention_filter = static_cast<const td_api::chatMembersFilterMention *>(filter.get());
919 top_thread_message_id_ = MessageId(mention_filter->message_thread_id_);
920 if (!top_thread_message_id_.is_valid() || !top_thread_message_id_.is_server()) {
921 top_thread_message_id_ = MessageId();
922 }
923 type_ = Type::Mention;
924 break;
925 }
926 case td_api::chatMembersFilterBots::ID:
927 type_ = Type::Bots;
928 break;
929 default:
930 UNREACHABLE();
931 type_ = Type::Members;
932 break;
933 }
934 }
935
get_supergroup_members_filter_object(const string & query) const936 td_api::object_ptr<td_api::SupergroupMembersFilter> DialogParticipantsFilter::get_supergroup_members_filter_object(
937 const string &query) const {
938 switch (type_) {
939 case Type::Contacts:
940 return td_api::make_object<td_api::supergroupMembersFilterContacts>();
941 case Type::Administrators:
942 return td_api::make_object<td_api::supergroupMembersFilterAdministrators>();
943 case Type::Members:
944 return td_api::make_object<td_api::supergroupMembersFilterSearch>(query);
945 case Type::Restricted:
946 return td_api::make_object<td_api::supergroupMembersFilterRestricted>(query);
947 case Type::Banned:
948 return td_api::make_object<td_api::supergroupMembersFilterBanned>(query);
949 case Type::Mention:
950 return td_api::make_object<td_api::supergroupMembersFilterMention>(query, top_thread_message_id_.get());
951 case Type::Bots:
952 return td_api::make_object<td_api::supergroupMembersFilterBots>();
953 default:
954 UNREACHABLE();
955 return nullptr;
956 }
957 }
958
has_query() const959 bool DialogParticipantsFilter::has_query() const {
960 switch (type_) {
961 case Type::Members:
962 case Type::Restricted:
963 case Type::Banned:
964 case Type::Mention:
965 return true;
966 case Type::Contacts:
967 case Type::Administrators:
968 case Type::Bots:
969 return false;
970 default:
971 UNREACHABLE();
972 return false;
973 }
974 }
975
is_dialog_participant_suitable(const Td * td,const DialogParticipant & participant) const976 bool DialogParticipantsFilter::is_dialog_participant_suitable(const Td *td,
977 const DialogParticipant &participant) const {
978 switch (type_) {
979 case Type::Contacts:
980 return participant.dialog_id_.get_type() == DialogType::User &&
981 td->contacts_manager_->is_user_contact(participant.dialog_id_.get_user_id());
982 case Type::Administrators:
983 return participant.status_.is_administrator();
984 case Type::Members:
985 return participant.status_.is_member();
986 case Type::Restricted:
987 return participant.status_.is_restricted();
988 case Type::Banned:
989 return participant.status_.is_banned();
990 case Type::Mention:
991 return true;
992 case Type::Bots:
993 return participant.dialog_id_.get_type() == DialogType::User &&
994 td->contacts_manager_->is_user_bot(participant.dialog_id_.get_user_id());
995 default:
996 UNREACHABLE();
997 return false;
998 }
999 }
1000
1001 } // namespace td
1002