Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions src/utils/moderation/blocked_extension.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#ifndef BLOCKED_EXTENSION_H
#define BLOCKED_EXTENSION_H

#include <algorithm>
#include <array>
#include <cctype>
#include <string_view>

namespace moderation {
inline constexpr auto blockedExtensions = std::to_array<std::string_view>({
".exe", ".dll", ".bat", ".cmd", ".scr", ".msi", ".ps1"
});

inline bool hasBlockedExtension(std::string_view filename)
{
const auto dot = filename.find_last_of('.');
if (dot == std::string_view::npos)
return false;

const std::string_view extension = filename.substr(dot);

return std::ranges::any_of(blockedExtensions,
[extension](const std::string_view blocked) {
return extension.size() == blocked.size()
&& std::ranges::equal(extension, blocked,
[](const char lhs, const char rhs) {
return std::tolower(static_cast<unsigned char>(lhs))
== std::tolower(static_cast<unsigned char>(rhs));
});
});
}
}

#endif // BLOCKED_EXTENSION_H
22 changes: 22 additions & 0 deletions src/utils/moderation/moderation.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include "moderation.h"
#include "../../globals/globals.h"

#include "blocked_extension.h"

ModerationService::ModerationService(dpp::cluster& bot) : bot(bot) {}

void ModerationService::cleanupOldEntries(const std::chrono::steady_clock::time_point& now)
Expand Down Expand Up @@ -38,6 +40,13 @@ std::string ModerationService::makeMessageSignature(const dpp::message& msg)
return signature;
}

bool ModerationService::hasBlockedAttachment(const dpp::message& msg)
{
return std::any_of(
msg.attachments.begin(), msg.attachments.end(),
[](const dpp::attachment& att) { return moderation::hasBlockedExtension(att.filename); });
}

bool ModerationService::handleMessage(const dpp::message_create_t& event)
{
if (event.msg.author.is_bot())
Expand All @@ -48,6 +57,19 @@ bool ModerationService::handleMessage(const dpp::message_create_t& event)
event.msg.embeds.empty())
return false;

if (hasBlockedAttachment(event.msg))
{
bot.message_delete(event.msg.id, event.msg.channel_id);

dpp::message blockMessage(
event.msg.channel_id,
dpp::utility::user_mention(event.msg.author.id) + " " + std::string(executableBlockMsg));
blockMessage.set_allowed_mentions(false, false, false, false, {event.msg.author.id}, {});
bot.message_create(blockMessage);

return true;
}

const auto now = std::chrono::steady_clock::now();
const auto userId = event.msg.author.id;
const std::string signature = makeMessageSignature(event.msg);
Expand Down
5 changes: 5 additions & 0 deletions src/utils/moderation/moderation.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ class ModerationService
"You have been jailed as you posted the same message on multiple channels. "
"Please contact a staff member if you think this is a mistake.";

static constexpr std::string_view executableBlockMsg =
"Your message contained an executable attachment, "
"which is not allowed and has been removed.";

struct PostedMessage
{
dpp::snowflake channelId{};
Expand All @@ -49,6 +53,7 @@ class ModerationService
};

static std::string makeMessageSignature(const dpp::message& msg);
static bool hasBlockedAttachment(const dpp::message& msg);
void cleanupOldEntries(const std::chrono::steady_clock::time_point& now);

dpp::cluster& bot;
Expand Down
Loading