From 7f12ac710732dc33acff52c7a32e25ca268a7fac Mon Sep 17 00:00:00 2001 From: Sheldan <5037282+Sheldan@users.noreply.github.com> Date: Sun, 29 Mar 2026 11:02:47 +0200 Subject: [PATCH] [AB-xxx] adding command to automatically ban all honeypot users refactored honeypot listener into a service fixing transfer credits not requiring the inputs --- .../command/economy/TransferCredits.java | 2 - .../moderation/command/HoneyPotBan.java | 153 ++++++++++++++++++ .../listener/HoneyPotRoleAddedListener.java | 95 ++--------- .../listener/HoneyPotServiceBean.java | 115 +++++++++++++ .../migrations/1.6.21/collection.xml | 6 + .../migrations/1.6.21/seedData/command.xml | 16 ++ .../migrations/1.6.21/seedData/data.xml | 6 + .../migrations/moderation-changeLog.xml | 1 + .../command/HoneyPotBanResponseModel.java | 10 ++ .../core/service/MemberServiceBean.java | 7 + .../abstracto/core/service/MemberService.java | 1 + 11 files changed, 325 insertions(+), 87 deletions(-) create mode 100644 abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/java/dev/sheldan/abstracto/moderation/command/HoneyPotBan.java create mode 100644 abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/java/dev/sheldan/abstracto/moderation/listener/HoneyPotServiceBean.java create mode 100644 abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/resources/migrations/1.6.21/collection.xml create mode 100644 abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/resources/migrations/1.6.21/seedData/command.xml create mode 100644 abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/resources/migrations/1.6.21/seedData/data.xml create mode 100644 abstracto-application/abstracto-modules/moderation/moderation-int/src/main/java/dev/sheldan/abstracto/moderation/model/template/command/HoneyPotBanResponseModel.java diff --git a/abstracto-application/abstracto-modules/entertainment/entertainment-impl/src/main/java/dev/sheldan/abstracto/entertainment/command/economy/TransferCredits.java b/abstracto-application/abstracto-modules/entertainment/entertainment-impl/src/main/java/dev/sheldan/abstracto/entertainment/command/economy/TransferCredits.java index b17dd2c84..8314952b7 100644 --- a/abstracto-application/abstracto-modules/entertainment/entertainment-impl/src/main/java/dev/sheldan/abstracto/entertainment/command/economy/TransferCredits.java +++ b/abstracto-application/abstracto-modules/entertainment/entertainment-impl/src/main/java/dev/sheldan/abstracto/entertainment/command/economy/TransferCredits.java @@ -74,7 +74,6 @@ public class TransferCredits extends AbstractConditionableCommand { .name(MEMBER_PARAMETER) .templated(true) .type(Member.class) - .optional(true) .build(); Parameter amountParameter = Parameter @@ -82,7 +81,6 @@ public class TransferCredits extends AbstractConditionableCommand { .name(AMOUNT_PARAMETER) .templated(true) .type(Integer.class) - .optional(true) .build(); List parameters = Arrays.asList(memberParameter, amountParameter); diff --git a/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/java/dev/sheldan/abstracto/moderation/command/HoneyPotBan.java b/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/java/dev/sheldan/abstracto/moderation/command/HoneyPotBan.java new file mode 100644 index 000000000..7eacd01d0 --- /dev/null +++ b/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/java/dev/sheldan/abstracto/moderation/command/HoneyPotBan.java @@ -0,0 +1,153 @@ +package dev.sheldan.abstracto.moderation.command; + +import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand; +import dev.sheldan.abstracto.core.command.config.CommandConfiguration; +import dev.sheldan.abstracto.core.command.config.HelpInfo; +import dev.sheldan.abstracto.core.command.config.Parameter; +import dev.sheldan.abstracto.core.command.execution.CommandResult; +import dev.sheldan.abstracto.core.config.FeatureDefinition; +import dev.sheldan.abstracto.core.interaction.InteractionService; +import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig; +import dev.sheldan.abstracto.core.interaction.slash.SlashCommandPrivilegeLevels; +import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService; +import dev.sheldan.abstracto.core.service.ConfigService; +import dev.sheldan.abstracto.core.utils.CompletableFutureList; +import dev.sheldan.abstracto.core.utils.FutureUtils; +import dev.sheldan.abstracto.core.utils.ParseUtils; +import dev.sheldan.abstracto.moderation.config.ModerationModuleDefinition; +import dev.sheldan.abstracto.moderation.config.ModerationSlashCommandNames; +import dev.sheldan.abstracto.moderation.config.feature.HoneyPotFeatureConfig; +import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition; +import dev.sheldan.abstracto.moderation.listener.HoneyPotServiceBean; +import dev.sheldan.abstracto.moderation.model.template.command.HoneyPotBanResponseModel; +import java.time.Duration; +import java.time.Instant; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.Role; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.InteractionHook; +import org.apache.commons.lang3.tuple.Pair; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + + +@Component +public class HoneyPotBan extends AbstractConditionableCommand { + + private static final String DURATION_PARAMETER = "duration"; + private static final String HONEYPOT_BAN_RESPONSE = "honeypotBan_response"; + private static final String HONEYPOT_BAN_COMMAND = "honeypotBan"; + + @Autowired + private HoneyPotBan self; + + @Autowired + private SlashCommandParameterService slashCommandParameterService; + + @Autowired + private HoneyPotServiceBean honeyPotServiceBean; + + @Autowired + private InteractionService interactionService; + + @Autowired + private ConfigService configService; + + @Override + public CompletableFuture executeSlash(SlashCommandInteractionEvent event) { + Duration duration; + if(slashCommandParameterService.hasCommandOption(DURATION_PARAMETER, event)) { + String durationStr = slashCommandParameterService.getCommandOption(DURATION_PARAMETER, event, Duration.class, String.class); + duration = ParseUtils.parseDuration(durationStr); + } else { + Long ignoredSeconds = + configService.getLongValueOrConfigDefault(HoneyPotFeatureConfig.HONEYPOT_IGNORED_JOIN_DURATION_SECONDS, event.getGuild().getIdLong()); + duration = Duration.ofSeconds(ignoredSeconds); + } + + return event.deferReply(false).submit() + .thenCompose(hook -> self.banEveryHoneypotMember(hook, event.getGuild(), duration)) + .thenCompose(banResponse -> self.sendResponse(banResponse)) + .thenApply(interactionHook -> CommandResult.fromSuccess()); + } + + @Transactional + public CompletableFuture sendResponse(Pair banResponse) { + HoneyPotBanResponseModel responseModel = HoneyPotBanResponseModel + .builder() + .bannedMemberCount(banResponse.getRight()) + .build(); + return FutureUtils.toSingleFutureGeneric(interactionService.sendMessageToInteraction(HONEYPOT_BAN_RESPONSE, responseModel, banResponse.getLeft())); + } + + @Transactional + public CompletableFuture> banEveryHoneypotMember(InteractionHook hook, Guild guild, Duration duration) { + Instant maxJoinAge; + if(duration != null) { + maxJoinAge = Instant.now().minus(duration); + } else { + maxJoinAge = Instant.now(); + } + List currentMembersWithHoneypotRole = honeyPotServiceBean.getCurrentMembersWithHoneypotRole(guild) + .stream().filter(member -> member.getTimeJoined().toInstant().isBefore(maxJoinAge)) + .toList(); + Role honeyPotRole = guild.getRoleById(honeyPotServiceBean.getHoneyPotRoleId(guild.getIdLong())); + List> futures = currentMembersWithHoneypotRole.stream().map(member -> + honeyPotServiceBean.banForHoneyPot(member, honeyPotRole) + ).toList(); + Integer memberCount = currentMembersWithHoneypotRole.size(); + CompletableFutureList futureList = new CompletableFutureList<>(futures); + return futureList.getMainFuture() + .thenApply(unused -> Pair.of(hook, memberCount)); + } + + @Override + public CommandConfiguration getConfiguration() { + + Parameter durationParameter = Parameter + .builder() + .name(DURATION_PARAMETER) + .templated(true) + .type(String.class) + .optional(true) + .build(); + + + List parameters = Arrays.asList(durationParameter); + HelpInfo helpInfo = HelpInfo + .builder() + .templated(true) + .hasExample(true) + .build(); + + SlashCommandConfig slashCommandConfig = SlashCommandConfig + .builder() + .enabled(true) + .rootCommandName(ModerationSlashCommandNames.MODERATION) + .defaultPrivilege(SlashCommandPrivilegeLevels.INVITER) + .commandName("honeypotban") + .build(); + + return CommandConfiguration.builder() + .name(HONEYPOT_BAN_COMMAND) + .module(ModerationModuleDefinition.MODERATION) + .templated(true) + .async(true) + .slashCommandConfig(slashCommandConfig) + .slashCommandOnly(true) + .supportsEmbedException(true) + .parameters(parameters) + .help(helpInfo) + .build(); + } + + @Override + public FeatureDefinition getFeature() { + return ModerationFeatureDefinition.HONEYPOT; + } +} diff --git a/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/java/dev/sheldan/abstracto/moderation/listener/HoneyPotRoleAddedListener.java b/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/java/dev/sheldan/abstracto/moderation/listener/HoneyPotRoleAddedListener.java index e197eeee0..2a0540dd5 100644 --- a/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/java/dev/sheldan/abstracto/moderation/listener/HoneyPotRoleAddedListener.java +++ b/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/java/dev/sheldan/abstracto/moderation/listener/HoneyPotRoleAddedListener.java @@ -4,97 +4,44 @@ import dev.sheldan.abstracto.core.config.FeatureDefinition; import dev.sheldan.abstracto.core.config.ListenerPriority; import dev.sheldan.abstracto.core.listener.DefaultListenerResult; import dev.sheldan.abstracto.core.listener.sync.jda.RoleAddedListener; -import dev.sheldan.abstracto.core.models.ConditionContextInstance; -import dev.sheldan.abstracto.core.models.ServerUser; -import dev.sheldan.abstracto.core.models.database.AUserInAServer; import dev.sheldan.abstracto.core.models.listener.RoleAddedModel; -import dev.sheldan.abstracto.core.models.template.display.MemberDisplay; -import dev.sheldan.abstracto.core.models.template.display.RoleDisplay; -import dev.sheldan.abstracto.core.service.ConditionService; -import dev.sheldan.abstracto.core.service.ConfigService; import dev.sheldan.abstracto.core.service.RoleService; -import dev.sheldan.abstracto.core.service.SystemCondition; -import dev.sheldan.abstracto.core.service.management.UserInServerManagementService; -import dev.sheldan.abstracto.core.templating.service.TemplateService; -import dev.sheldan.abstracto.moderation.config.feature.HoneyPotFeatureConfig; import dev.sheldan.abstracto.moderation.config.feature.ModerationFeatureDefinition; -import dev.sheldan.abstracto.moderation.model.listener.HoneyPotReasonModel; -import dev.sheldan.abstracto.moderation.service.BanService; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; import lombok.extern.slf4j.Slf4j; import net.dv8tion.jda.api.entities.ISnowflake; -import net.dv8tion.jda.api.entities.Member; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import java.time.Duration; -import java.time.Instant; -import java.time.temporal.ChronoUnit; -import java.util.HashMap; -import java.util.Map; @Component @Slf4j public class HoneyPotRoleAddedListener implements RoleAddedListener { - @Autowired - private ConfigService configService; - - @Autowired - private BanService banService; - - @Autowired - private TemplateService templateService; - - @Autowired - private ConditionService conditionService; - - @Autowired - private UserInServerManagementService userInServerManagementService; - @Autowired private RoleService roleService; - private static final String HONEYPOT_BAN_REASON_TEMPLATE = "honeypot_ban_reason"; - - private static final String LEVEL_CONDITION_USER_ID_PARAMETER = "userId"; - private static final String LEVEL_CONDITION_LEVEL_PARAMETER = "level"; - private static final String LEVEL_CONDITION_SERVER_PARAMETER = "serverId"; - - private static final String LEVEL_CONDITION_NAME = "HAS_LEVEL"; + @Autowired + private HoneyPotServiceBean honeyPotServiceBean; @Override public DefaultListenerResult execute(RoleAddedModel model) { - Long honeyPotRoleId = configService.getLongValueOrConfigDefault(HoneyPotFeatureConfig.HONEYPOT_ROLE_ID, model.getServerId()); + Long honeyPotRoleId = honeyPotServiceBean.getHoneyPotRoleId(model.getServerId()); if(honeyPotRoleId == 0) { log.info("Server {} has honeypot feature enabled, but still default honeypot role config - Ignoring.", model.getServerId()); return DefaultListenerResult.IGNORED; } if(honeyPotRoleId.equals(model.getRoleId())) { - Integer levelToSkipBan = configService.getLongValueOrConfigDefault(HoneyPotFeatureConfig.HONEYPOT_IGNORED_LEVEL, model.getServerId()).intValue(); - Long amountOfSecondsToIgnore = configService.getLongValueOrConfigDefault(HoneyPotFeatureConfig.HONEYPOT_IGNORED_JOIN_DURATION_SECONDS, model.getServerId()); - boolean allowed = userHasLevel(model.getTargetMember(), levelToSkipBan) || userJoinedLongerThanSeconds(model.getTargetMember(), amountOfSecondsToIgnore); - if(allowed) { - log.info("User {} in server {} has at least level {} or joined more than {} seconds ago and will not get banned by honeypot. All existing roles besides {} will be removed.", - model.getTargetUser().getUserId(), model.getTargetUser().getServerId(), levelToSkipBan, amountOfSecondsToIgnore, honeyPotRoleId); - cleanupRolesBesidesHoneyPot(model, honeyPotRoleId); - } else { + boolean fellIntoHoneyPot = honeyPotServiceBean.fellIntoHoneyPot(model.getServerId(), model.getTargetMember()); + if (fellIntoHoneyPot) { log.info("Banning user {} in guild {} due to role {}.", model.getTargetUser().getUserId(), model.getTargetUser().getServerId(), model.getRoleId()); - HoneyPotReasonModel reasonModel = HoneyPotReasonModel - .builder() - .memberDisplay(MemberDisplay.fromMember(model.getTargetMember())) - .roleDisplay(RoleDisplay.fromRole(model.getRole())) - .build(); - String banReason = templateService.renderTemplate(HONEYPOT_BAN_REASON_TEMPLATE, reasonModel, model.getServerId()); - banService.banUserWithNotification(model.getTargetUser(), banReason, ServerUser.fromMember(model.getTargetMember().getGuild().getSelfMember()), - model.getTargetMember().getGuild(), Duration.ofDays(7)).thenAccept(banResult -> { - log.info("Banned user {} in guild {} due to role {}.", model.getTargetUser().getUserId(), model.getTargetUser().getServerId(), model.getRoleId()); - }).exceptionally(throwable -> { - log.error("Failed to ban user {} in guild {} due to role {}.", model.getTargetUser().getUserId(), model.getTargetUser().getServerId(), model.getRoleId(), throwable); - return null; - }); + honeyPotServiceBean.banForHoneyPot(model.getTargetMember(), model.getRole()); + } else { + log.info("User {} in server {} will not get banned by honeypot. All existing roles besides {} will be removed.", + model.getTargetUser().getUserId(), model.getTargetUser().getServerId(), honeyPotRoleId); + cleanupRolesBesidesHoneyPot(model, honeyPotRoleId); } return DefaultListenerResult.PROCESSED; } else { @@ -126,28 +73,6 @@ public class HoneyPotRoleAddedListener implements RoleAddedListener { } } - private boolean userHasLevel(Member member, Integer level) { - log.info("Checking if member {} is ignored to click on the honeypot in server {}.", member.getIdLong(),member.getGuild().getIdLong()); - Map parameters = new HashMap<>(); - AUserInAServer userInAServer = userInServerManagementService.loadOrCreateUser(member); - parameters.put(LEVEL_CONDITION_USER_ID_PARAMETER, userInAServer.getUserInServerId()); - parameters.put(LEVEL_CONDITION_LEVEL_PARAMETER, level); - parameters.put(LEVEL_CONDITION_SERVER_PARAMETER, member.getGuild().getIdLong()); - ConditionContextInstance contextInstance = ConditionContextInstance - .builder() - .conditionName(LEVEL_CONDITION_NAME) - .parameters(parameters) - .build(); - SystemCondition.Result result = conditionService.checkConditions(contextInstance); - return SystemCondition.Result.isSuccessful(result); - } - - private boolean userJoinedLongerThanSeconds(Member member, Long seconds) { - log.info("Checking if member {} joined the server more than {} seconds ago.", member.getIdLong(), seconds); - // the incorrectness of timejoined should not matter, we chunk anyway - return member.getTimeJoined().toInstant().isBefore(Instant.now().minus(seconds, ChronoUnit.SECONDS)); - } - @Override public FeatureDefinition getFeature() { return ModerationFeatureDefinition.HONEYPOT; diff --git a/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/java/dev/sheldan/abstracto/moderation/listener/HoneyPotServiceBean.java b/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/java/dev/sheldan/abstracto/moderation/listener/HoneyPotServiceBean.java new file mode 100644 index 000000000..8468059ad --- /dev/null +++ b/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/java/dev/sheldan/abstracto/moderation/listener/HoneyPotServiceBean.java @@ -0,0 +1,115 @@ +package dev.sheldan.abstracto.moderation.listener; + +import dev.sheldan.abstracto.core.models.ConditionContextInstance; +import dev.sheldan.abstracto.core.models.ServerUser; +import dev.sheldan.abstracto.core.models.database.AUserInAServer; +import dev.sheldan.abstracto.core.models.template.display.MemberDisplay; +import dev.sheldan.abstracto.core.models.template.display.RoleDisplay; +import dev.sheldan.abstracto.core.service.ConditionService; +import dev.sheldan.abstracto.core.service.ConfigService; +import dev.sheldan.abstracto.core.service.MemberService; +import dev.sheldan.abstracto.core.service.SystemCondition; +import dev.sheldan.abstracto.core.service.management.UserInServerManagementService; +import dev.sheldan.abstracto.core.templating.service.TemplateService; +import dev.sheldan.abstracto.moderation.config.feature.HoneyPotFeatureConfig; +import dev.sheldan.abstracto.moderation.model.listener.HoneyPotReasonModel; +import dev.sheldan.abstracto.moderation.service.BanService; +import java.time.Duration; +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import lombok.extern.slf4j.Slf4j; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.Role; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +@Slf4j +public class HoneyPotServiceBean { + + @Autowired + private ConfigService configService; + + @Autowired + private UserInServerManagementService userInServerManagementService; + + @Autowired + private ConditionService conditionService; + + @Autowired + private TemplateService templateService; + + @Autowired + private BanService banService; + + @Autowired + private MemberService memberService; + + private static final String LEVEL_CONDITION_USER_ID_PARAMETER = "userId"; + private static final String LEVEL_CONDITION_LEVEL_PARAMETER = "level"; + private static final String LEVEL_CONDITION_SERVER_PARAMETER = "serverId"; + private static final String LEVEL_CONDITION_NAME = "HAS_LEVEL"; + private static final String HONEYPOT_BAN_REASON_TEMPLATE = "honeypot_ban_reason"; + + + public Long getHoneyPotRoleId(Long serverId) { + return configService.getLongValueOrConfigDefault(HoneyPotFeatureConfig.HONEYPOT_ROLE_ID, serverId); + } + + public boolean fellIntoHoneyPot(Long serverId, Member member) { + Integer levelToSkipBan = configService.getLongValueOrConfigDefault(HoneyPotFeatureConfig.HONEYPOT_IGNORED_LEVEL, serverId).intValue(); + Long amountOfSecondsToIgnore = configService.getLongValueOrConfigDefault(HoneyPotFeatureConfig.HONEYPOT_IGNORED_JOIN_DURATION_SECONDS, serverId); + boolean allowed = userHasLevel(member, levelToSkipBan) || userJoinedLongerThanSeconds(member, amountOfSecondsToIgnore); + return !allowed; + } + + public List getCurrentMembersWithHoneypotRole(Guild guild) { + return memberService.getMembersWithRole(guild.getIdLong(), getHoneyPotRoleId(guild.getIdLong())); + } + + public CompletableFuture banForHoneyPot(Member targetMember, Role role) { + HoneyPotReasonModel reasonModel = HoneyPotReasonModel + .builder() + .memberDisplay(MemberDisplay.fromMember(targetMember)) + .roleDisplay(RoleDisplay.fromRole(role)) + .build(); + ServerUser bannedUser = ServerUser.fromMember(targetMember); + String banReason = templateService.renderTemplate(HONEYPOT_BAN_REASON_TEMPLATE, reasonModel, bannedUser.getServerId()); + long roleId = role.getIdLong(); + return banService.banUserWithNotification(bannedUser, banReason, ServerUser.fromMember(targetMember.getGuild().getSelfMember()), + targetMember.getGuild(), Duration.ofDays(7)).thenAccept(banResult -> { + log.info("Banned user {} in guild {} due to role {}.", bannedUser.getUserId(), bannedUser.getServerId(), roleId); + }).exceptionally(throwable -> { + log.error("Failed to ban user {} in guild {} due to role {}.", bannedUser.getUserId(), bannedUser.getServerId(), roleId, throwable); + return null; + }); + } + + private boolean userHasLevel(Member member, Integer level) { + log.info("Checking if member {} is ignored to click on the honeypot in server {}.", member.getIdLong(),member.getGuild().getIdLong()); + Map parameters = new HashMap<>(); + AUserInAServer userInAServer = userInServerManagementService.loadOrCreateUser(member); + parameters.put(LEVEL_CONDITION_USER_ID_PARAMETER, userInAServer.getUserInServerId()); + parameters.put(LEVEL_CONDITION_LEVEL_PARAMETER, level); + parameters.put(LEVEL_CONDITION_SERVER_PARAMETER, member.getGuild().getIdLong()); + ConditionContextInstance contextInstance = ConditionContextInstance + .builder() + .conditionName(LEVEL_CONDITION_NAME) + .parameters(parameters) + .build(); + SystemCondition.Result result = conditionService.checkConditions(contextInstance); + return SystemCondition.Result.isSuccessful(result); + } + + private boolean userJoinedLongerThanSeconds(Member member, Long seconds) { + log.info("Checking if member {} joined the server more than {} seconds ago.", member.getIdLong(), seconds); + // the incorrectness of timejoined should not matter, we chunk anyway + return member.getTimeJoined().toInstant().isBefore(Instant.now().minus(seconds, ChronoUnit.SECONDS)); + } + +} diff --git a/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/resources/migrations/1.6.21/collection.xml b/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/resources/migrations/1.6.21/collection.xml new file mode 100644 index 000000000..1bbc30fef --- /dev/null +++ b/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/resources/migrations/1.6.21/collection.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/resources/migrations/1.6.21/seedData/command.xml b/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/resources/migrations/1.6.21/seedData/command.xml new file mode 100644 index 000000000..9f1ae41ac --- /dev/null +++ b/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/resources/migrations/1.6.21/seedData/command.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/resources/migrations/1.6.21/seedData/data.xml b/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/resources/migrations/1.6.21/seedData/data.xml new file mode 100644 index 000000000..e18fc4181 --- /dev/null +++ b/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/resources/migrations/1.6.21/seedData/data.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/resources/migrations/moderation-changeLog.xml b/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/resources/migrations/moderation-changeLog.xml index dca278699..9b61f2765 100644 --- a/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/resources/migrations/moderation-changeLog.xml +++ b/abstracto-application/abstracto-modules/moderation/moderation-impl/src/main/resources/migrations/moderation-changeLog.xml @@ -13,4 +13,5 @@ + \ No newline at end of file diff --git a/abstracto-application/abstracto-modules/moderation/moderation-int/src/main/java/dev/sheldan/abstracto/moderation/model/template/command/HoneyPotBanResponseModel.java b/abstracto-application/abstracto-modules/moderation/moderation-int/src/main/java/dev/sheldan/abstracto/moderation/model/template/command/HoneyPotBanResponseModel.java new file mode 100644 index 000000000..4b9d7fccd --- /dev/null +++ b/abstracto-application/abstracto-modules/moderation/moderation-int/src/main/java/dev/sheldan/abstracto/moderation/model/template/command/HoneyPotBanResponseModel.java @@ -0,0 +1,10 @@ +package dev.sheldan.abstracto.moderation.model.template.command; + +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +public class HoneyPotBanResponseModel { + private Integer bannedMemberCount; +} diff --git a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/MemberServiceBean.java b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/MemberServiceBean.java index e4e85dfa2..3ad09c372 100644 --- a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/MemberServiceBean.java +++ b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/MemberServiceBean.java @@ -92,6 +92,13 @@ public class MemberServiceBean implements MemberService { return getMemberInServerAsync(serverUser.getServerId(), serverUser.getUserId()); } + @Override + public List getMembersWithRole(Long serverId, Long roleId) { + Guild guildById = guildService.getGuildById(serverId); + Role role = guildById.getRoleById(roleId); + return guildById.getMembersWithRoles(List.of(role)); + } + @Override public CompletableFuture retrieveUserById(Long userId) { return botService.getInstance().retrieveUserById(userId).submit(); diff --git a/abstracto-application/core/core-int/src/main/java/dev/sheldan/abstracto/core/service/MemberService.java b/abstracto-application/core/core-int/src/main/java/dev/sheldan/abstracto/core/service/MemberService.java index 718245d84..1ece4e414 100644 --- a/abstracto-application/core/core-int/src/main/java/dev/sheldan/abstracto/core/service/MemberService.java +++ b/abstracto-application/core/core-int/src/main/java/dev/sheldan/abstracto/core/service/MemberService.java @@ -21,6 +21,7 @@ public interface MemberService { CompletableFuture getMemberInServerAsync(Long serverId, Long memberId); CompletableFuture> getMembersInServerAsync(Long serverId, List memberIds); CompletableFuture retrieveMemberInServer(ServerUser serverUser); + List getMembersWithRole(Long serverId, Long roleId); CompletableFuture retrieveUserById(Long userId); boolean isUserInGuild(AUserInAServer aUserInAServer); boolean isUserInGuild(Guild guild, AUserInAServer aUserInAServer);