Fixed reporting to anti-spam incorrect message id from admin log.

This commit is contained in:
23rd 2022-12-03 14:19:14 +03:00
parent beb062dd64
commit badebb261b
7 changed files with 87 additions and 49 deletions

View File

@ -829,20 +829,32 @@ void InnerWidget::addEvents(Direction direction, const QVector<MTPChannelAdminLo
? _items
: newItemsForDownDirection;
addToItems.reserve(oldItemsCount + events.size() * 2);
const auto antiSpamUserId = _antiSpamValidator.userId();
for (const auto &event : events) {
const auto &data = event.data();
const auto id = data.vid().v;
if (_eventIds.find(id) != _eventIds.end()) {
return;
}
const auto rememberRealMsgId = (antiSpamUserId
== peerToUser(peerFromUser(data.vuser_id())));
auto count = 0;
const auto addOne = [&](OwnedItem item, TimeId sentDate) {
const auto addOne = [&](
OwnedItem item,
TimeId sentDate,
MsgId realId) {
if (sentDate) {
_itemDates.emplace(item->data(), sentDate);
}
_eventIds.emplace(id);
_itemsByData.emplace(item->data(), item.get());
if (rememberRealMsgId && realId) {
_antiSpamValidator.addEventMsgId(
item->data()->fullId(),
realId);
}
addToItems.push_back(std::move(item));
++count;
};

View File

@ -326,7 +326,7 @@ private:
Qt::CursorShape _cursor = style::cur_default;
base::unique_qptr<Ui::PopupMenu> _menu;
const AntiSpamMenu::AntiSpamValidator _antiSpamValidator;
AntiSpamMenu::AntiSpamValidator _antiSpamValidator;
QPoint _trippleClickPoint;
base::Timer _trippleClickTimer;

View File

@ -60,16 +60,26 @@ TextWithEntities PrepareText(
return result;
}
TimeId ExtractSentDate(const MTPMessage &message) {
return message.match([&](const MTPDmessageEmpty &) {
[[nodiscard]] TimeId ExtractSentDate(const MTPMessage &message) {
return message.match([](const MTPDmessageEmpty &) {
return 0;
}, [&](const MTPDmessageService &data) {
}, [](const MTPDmessageService &data) {
return data.vdate().v;
}, [&](const MTPDmessage &data) {
}, [](const MTPDmessage &data) {
return data.vdate().v;
});
}
[[nodiscard]] MsgId ExtractRealMsgId(const MTPMessage &message) {
return MsgId(message.match([](const MTPDmessageEmpty &) {
return 0;
}, [](const MTPDmessageService &data) {
return data.vid().v;
}, [](const MTPDmessage &data) {
return data.vid().v;
}));
}
MTPMessage PrepareLogMessage(const MTPMessage &message, TimeId newDate) {
return message.match([&](const MTPDmessageEmpty &data) {
return MTP_messageEmpty(
@ -680,7 +690,7 @@ void GenerateItems(
not_null<HistoryView::ElementDelegate*> delegate,
not_null<History*> history,
const MTPDchannelAdminLogEvent &event,
Fn<void(OwnedItem item, TimeId sentDate)> callback) {
Fn<void(OwnedItem item, TimeId sentDate, MsgId)> callback) {
Expects(history->peer->isChannel());
using LogTitle = MTPDchannelAdminLogEventActionChangeTitle;
@ -741,8 +751,9 @@ void GenerateItems(
const auto date = event.vdate().v;
const auto addPart = [&](
not_null<HistoryItem*> item,
TimeId sentDate = 0) {
return callback(OwnedItem(delegate, item), sentDate);
TimeId sentDate = 0,
MsgId realId = MsgId()) {
return callback(OwnedItem(delegate, item), sentDate, realId);
};
const auto fromName = from->name();
@ -751,16 +762,20 @@ void GenerateItems(
const auto addSimpleServiceMessage = [&](
const TextWithEntities &text,
MsgId realId = MsgId(),
PhotoData *photo = nullptr) {
auto message = HistoryService::PreparedText{ text };
message.links.push_back(fromLink);
addPart(history->makeServiceMessage(
history->nextNonHistoryEntryId(),
MessageFlag::AdminLogEntry,
date,
std::move(message),
peerToUser(from->id),
photo));
addPart(
history->makeServiceMessage(
history->nextNonHistoryEntryId(),
MessageFlag::AdminLogEntry,
date,
std::move(message),
peerToUser(from->id),
photo),
0,
realId);
};
const auto createChangeTitle = [&](const LogTitle &action) {
@ -865,7 +880,7 @@ void GenerateItems(
lt_from,
fromLinkText,
Ui::Text::WithEntities);
addSimpleServiceMessage(text, photo);
addSimpleServiceMessage(text, MsgId(), photo);
}, [&](const MTPDphotoEmpty &data) {
const auto text = (channel->isMegagroup()
? tr::lng_admin_log_removed_photo_group
@ -905,6 +920,7 @@ void GenerateItems(
const auto createUpdatePinned = [&](const LogPin &action) {
action.vmessage().match([&](const MTPDmessage &data) {
const auto pinned = data.is_pinned();
const auto realId = ExtractRealMsgId(action.vmessage());
const auto text = (pinned
? tr::lng_admin_log_pinned_message
: tr::lng_admin_log_unpinned_message)(
@ -912,7 +928,7 @@ void GenerateItems(
lt_from,
fromLinkText,
Ui::Text::WithEntities);
addSimpleServiceMessage(text);
addSimpleServiceMessage(text, realId);
const auto detachExistingItem = false;
addPart(
@ -921,7 +937,8 @@ void GenerateItems(
PrepareLogMessage(action.vmessage(), date),
MessageFlag::AdminLogEntry,
detachExistingItem),
ExtractSentDate(action.vmessage()));
ExtractSentDate(action.vmessage()),
realId);
}, [&](const auto &) {
const auto text = tr::lng_admin_log_unpinned_message(
tr::now,
@ -933,6 +950,8 @@ void GenerateItems(
};
const auto createEditMessage = [&](const LogEdit &action) {
const auto realId = ExtractRealMsgId(action.vnew_message());
const auto sentDate = ExtractSentDate(action.vnew_message());
const auto newValue = ExtractEditedText(
session,
action.vnew_message());
@ -964,7 +983,7 @@ void GenerateItems(
lt_from,
fromLinkText,
Ui::Text::WithEntities);
addSimpleServiceMessage(text);
addSimpleServiceMessage(text, realId);
const auto detachExistingItem = false;
const auto body = history->createItem(
@ -984,16 +1003,17 @@ void GenerateItems(
? tr::lng_admin_log_previous_caption
: tr::lng_admin_log_previous_message)(tr::now),
oldValue);
addPart(body);
addPart(body, sentDate, realId);
};
const auto createDeleteMessage = [&](const LogDelete &action) {
const auto realId = ExtractRealMsgId(action.vmessage());
const auto text = tr::lng_admin_log_deleted_message(
tr::now,
lt_from,
fromLinkText,
Ui::Text::WithEntities);
addSimpleServiceMessage(text);
addSimpleServiceMessage(text, realId);
const auto detachExistingItem = false;
addPart(
@ -1002,7 +1022,8 @@ void GenerateItems(
PrepareLogMessage(action.vmessage(), date),
MessageFlag::AdminLogEntry,
detachExistingItem),
ExtractSentDate(action.vmessage()));
ExtractSentDate(action.vmessage()),
realId);
};
const auto createParticipantJoin = [&](const LogJoin&) {
@ -1122,12 +1143,13 @@ void GenerateItems(
};
const auto createStopPoll = [&](const LogPoll &action) {
const auto realId = ExtractRealMsgId(action.vmessage());
const auto text = tr::lng_admin_log_stopped_poll(
tr::now,
lt_from,
fromLinkText,
Ui::Text::WithEntities);
addSimpleServiceMessage(text);
addSimpleServiceMessage(text, realId);
const auto detachExistingItem = false;
addPart(
@ -1136,7 +1158,8 @@ void GenerateItems(
PrepareLogMessage(action.vmessage(), date),
MessageFlag::AdminLogEntry,
detachExistingItem),
ExtractSentDate(action.vmessage()));
ExtractSentDate(action.vmessage()),
realId);
};
const auto createChangeLinkedChat = [&](const LogDiscussion &action) {
@ -1493,12 +1516,13 @@ void GenerateItems(
};
const auto createSendMessage = [&](const LogSendMessage &data) {
const auto realId = ExtractRealMsgId(data.vmessage());
const auto text = tr::lng_admin_log_sent_message(
tr::now,
lt_from,
fromLinkText,
Ui::Text::WithEntities);
addSimpleServiceMessage(text);
addSimpleServiceMessage(text, realId);
const auto detachExistingItem = false;
addPart(
@ -1507,7 +1531,8 @@ void GenerateItems(
PrepareLogMessage(data.vmessage(), date),
MessageFlag::AdminLogEntry,
detachExistingItem),
ExtractSentDate(data.vmessage()));
ExtractSentDate(data.vmessage()),
realId);
};
const auto createChangeAvailableReactions = [&](

View File

@ -22,7 +22,7 @@ void GenerateItems(
not_null<HistoryView::ElementDelegate*> delegate,
not_null<History*> history,
const MTPDchannelAdminLogEvent &event,
Fn<void(OwnedItem item, TimeId sentDate)> callback);
Fn<void(OwnedItem item, TimeId sentDate, MsgId)> callback);
// Smart pointer wrapper for HistoryItem* that destroys the owned item.
class OwnedItem {

View File

@ -147,14 +147,18 @@ UserData *AntiSpamValidator::maybeAppendUser() const {
return nullptr;
}
UserId AntiSpamValidator::userId() const {
return AntiSpamUserId(_channel);
}
void AntiSpamValidator::addAction(
not_null<Ui::PopupMenu*> menu,
FullMsgId fullId) const {
if (!fullId) {
FullMsgId fakeId) const {
if (!fakeId) {
return;
}
const auto antiSpamUserId = AntiSpamUserId(_channel);
const auto suggestReport = [&] {
const auto suggestReport = [&](MsgId eventId) {
const auto text = tr::lng_admin_log_antispam_menu_report_toast(
tr::now,
lt_link,
@ -187,29 +191,22 @@ void AntiSpamValidator::addAction(
_channel->session().api().request(
MTPchannels_ReportAntiSpamFalsePositive(
channel->inputChannel,
MTP_int(fullId.msg)
MTP_int(eventId)
)).done(showToast).send();
},
&st::menuIconAdmin);
};
const auto &data = _channel->owner();
const auto findItem = [&](FullMsgId id, int offset) {
id.msg.bare -= offset;
if (const auto item = data.message(id)) {
if (peerToUser(item->from()->id) == antiSpamUserId) {
suggestReport();
return true;
}
}
return false;
};
// Context menu on service message.
if (!findItem(fullId, 0)) {
// Take a previous.
if (findItem(fullId, 1)) {
{
const auto it = _itemEventMsgIds.find(fakeId);
if (it != end(_itemEventMsgIds)) {
suggestReport(it->second);
menu->addSeparator();
}
}
}
void AntiSpamValidator::addEventMsgId(FullMsgId fakeId, MsgId realId) {
_itemEventMsgIds.emplace(fakeId, realId);
}
} // namespace AntiSpamMenu

View File

@ -34,12 +34,16 @@ public:
void resolveUser(Fn<void()> finish) const;
[[nodiscard]] UserData *maybeAppendUser() const;
void addAction(not_null<Ui::PopupMenu*> menu, FullMsgId fullId) const;
[[nodiscard]] UserId userId() const;
void addAction(not_null<Ui::PopupMenu*> menu, FullMsgId fakeId) const;
void addEventMsgId(FullMsgId fakeId, MsgId realId);
private:
const not_null<ChannelData*> _channel;
const not_null<Window::SessionController*> _controller;
base::flat_map<FullMsgId, MsgId> _itemEventMsgIds;
};
} // namespace AntiSpamMenu

@ -1 +1 @@
Subproject commit 6c345d2076e0b1997ef64b13f617bf5afbaf396b
Subproject commit ff821bc3d79761a2b801bd067d38d2a4d7f766e3