sxcybot

Discord bot for OSRS based channels
git clone git://git.wimdupont.com/sxcybot.git
Log | Files | Refs | README | LICENSE

commit 3c10a0fe35c04594aa5024b2d2ea5b78722c7e36
parent 0bfb0130d093d1c44ebe6406d985ae81c6142de6
Author: Wim Dupont <wim@wimdupont.com>
Date:   Sat,  5 Oct 2024 14:39:28 +0200

role assigner permission update

Diffstat:
Msrc/main/java/com/wimdupont/sxcybot/listeners/AdminCommandListener.java | 53+++++++++++++++++------------------------------------
Msrc/main/java/com/wimdupont/sxcybot/listeners/admin/RoleAssignListener.java | 19+++++++++++++++++--
Asrc/main/java/com/wimdupont/sxcybot/services/AccessService.java | 43+++++++++++++++++++++++++++++++++++++++++++
Msrc/main/java/com/wimdupont/sxcybot/util/Constants.java | 14++++++++++++++
4 files changed, 91 insertions(+), 38 deletions(-)

diff --git a/src/main/java/com/wimdupont/sxcybot/listeners/AdminCommandListener.java b/src/main/java/com/wimdupont/sxcybot/listeners/AdminCommandListener.java @@ -9,28 +9,24 @@ import com.wimdupont.sxcybot.listeners.admin.EditPvmListener; import com.wimdupont.sxcybot.listeners.admin.EditRoleListener; import com.wimdupont.sxcybot.listeners.admin.EditRuleListener; import com.wimdupont.sxcybot.listeners.admin.RoleAssignListener; -import com.wimdupont.sxcybot.repository.guild.dao.GuildRole; -import com.wimdupont.sxcybot.services.guild.GuildRoleService; +import com.wimdupont.sxcybot.services.AccessService; import jakarta.annotation.Nonnull; -import net.dv8tion.jda.api.Permission; import net.dv8tion.jda.api.entities.Role; import net.dv8tion.jda.api.events.message.MessageReceivedEvent; import net.dv8tion.jda.api.hooks.ListenerAdapter; import org.springframework.stereotype.Component; -import java.util.List; -import java.util.function.Predicate; import java.util.stream.Stream; +import static com.wimdupont.sxcybot.util.Constants.ROLE_ACCESS.ADMIN_ROLE; +import static com.wimdupont.sxcybot.util.Constants.ROLE_ACCESS.GENERAL; +import static com.wimdupont.sxcybot.util.Constants.ROLE_ACCESS.GOD; +import static com.wimdupont.sxcybot.util.Constants.ROLE_ACCESS.STAFF_ROLE; +import static com.wimdupont.sxcybot.util.Constants.ROLE_ACCESS.TEACHER; + @Component public class AdminCommandListener extends ListenerAdapter { - private static final int GOD = 0; - private static final int ADMIN_ROLE = 1; - private static final int GENERAL = 3; - private static final int SUB_ADMIN = 5; - private static final int STAFF_ROLE = 10; - private static final int TEACHER = 20; private final EditRuleListener editRuleListener; private final EditBanlistListener editBanlistListener; @@ -39,7 +35,7 @@ public class AdminCommandListener extends ListenerAdapter { private final EditRoleListener editRoleListener; private final EditPvmListener editPvmListener; private final BossUpdateMultiplierListener bossUpdateMultiplierListener; - private final GuildRoleService guildRoleService; + private final AccessService accessService; public AdminCommandListener(EditRuleListener editRuleListener, EditBanlistListener editBanlistListener, @@ -48,7 +44,7 @@ public class AdminCommandListener extends ListenerAdapter { EditRoleListener editRoleListener, EditPvmListener editPvmListener, BossUpdateMultiplierListener bossUpdateMultiplierListener, - GuildRoleService guildRoleService) { + AccessService accessService) { this.editRuleListener = editRuleListener; this.editBanlistListener = editBanlistListener; this.roleAssignListener = roleAssignListener; @@ -56,7 +52,7 @@ public class AdminCommandListener extends ListenerAdapter { this.editRoleListener = editRoleListener; this.editPvmListener = editPvmListener; this.bossUpdateMultiplierListener = bossUpdateMultiplierListener; - this.guildRoleService = guildRoleService; + this.accessService = accessService; } public void executeCommand(@Nonnull MessageReceivedEvent event, Admin adminCommand) { @@ -65,35 +61,33 @@ public class AdminCommandListener extends ListenerAdapter { try { switch (adminCommand) { case EDITRULE -> { - isPrivileged(roleStream, event, ADMIN_ROLE); + accessService.isAllowed(roleStream, event, ADMIN_ROLE); editRuleListener.process(event); } case EDITBANLIST -> { - isPrivileged(roleStream, event, ADMIN_ROLE); + accessService.isAllowed(roleStream, event, ADMIN_ROLE); editBanlistListener.process(event); } case ROLE -> { - isPrivileged(roleStream, event, TEACHER); + accessService.isAllowed(roleStream, event, TEACHER); roleAssignListener.process(event); } case BANLIST -> { - isPrivileged(roleStream, event, STAFF_ROLE); + accessService.isAllowed(roleStream, event, STAFF_ROLE); banlistListener.process(event); } case EDITROLE -> { - isPrivileged(roleStream, event, GOD); + accessService.isAllowed(roleStream, event, GOD); editRoleListener.process(event); } case EDITPVM -> { - isPrivileged(roleStream, event, STAFF_ROLE); + accessService.isAllowed(roleStream, event, STAFF_ROLE); editPvmListener.process(event); } case EDITBOSS -> { - isPrivileged(roleStream, event, GENERAL); + accessService.isAllowed(roleStream, event, GENERAL); bossUpdateMultiplierListener.process(event); } - default -> { - } } } catch (InsufficientPrivilegesException e) { event.getChannel().sendMessage(e.getMessage()).queue(); @@ -101,17 +95,4 @@ public class AdminCommandListener extends ListenerAdapter { } } - private void isPrivileged(Stream<Role> roleStream, MessageReceivedEvent event, int elevation) throws InsufficientPrivilegesException { - List<GuildRole> guildRoles = guildRoleService.findAllByElevationLessThanEqual(elevation); - if (roleStream.noneMatch(hasPrivilege(event, guildRoles))) - throw new InsufficientPrivilegesException(guildRoles.stream().map(GuildRole::getDiscordId).toList()); - } - - private Predicate<Role> hasPrivilege(MessageReceivedEvent event, List<GuildRole> guildRoles) { - return f -> f.hasPermission(Permission.ADMINISTRATOR) - || (event.getMember() != null && event.getMember().isOwner()) - || guildRoles.stream() - .map(GuildRole::getDiscordId) - .anyMatch(e -> e.equalsIgnoreCase(f.getId())); - } } diff --git a/src/main/java/com/wimdupont/sxcybot/listeners/admin/RoleAssignListener.java b/src/main/java/com/wimdupont/sxcybot/listeners/admin/RoleAssignListener.java @@ -1,8 +1,10 @@ package com.wimdupont.sxcybot.listeners.admin; +import com.wimdupont.sxcybot.exceptions.InsufficientPrivilegesException; import com.wimdupont.sxcybot.listeners.EventWaiter; import com.wimdupont.sxcybot.listeners.Listener; import com.wimdupont.sxcybot.repository.guild.dao.GuildRole; +import com.wimdupont.sxcybot.services.AccessService; import com.wimdupont.sxcybot.services.guild.GuildRoleService; import com.wimdupont.sxcybot.util.Constants; import com.wimdupont.sxcybot.util.DiscordMemberFinderUtil; @@ -16,6 +18,9 @@ import org.springframework.stereotype.Component; import java.awt.Color; import java.util.Comparator; +import java.util.stream.Stream; + +import static com.wimdupont.sxcybot.util.Constants.ROLE_ACCESS.SUB_ADMIN; @Component public class RoleAssignListener implements Listener { @@ -24,13 +29,16 @@ public class RoleAssignListener implements Listener { private final EventWaiter eventWaiter; private final GuildRoleService guildRoleService; private final DiscordMemberFinderUtil discordMemberFinderUtil; + private final AccessService accessService; public RoleAssignListener(EventWaiter eventWaiter, GuildRoleService guildRoleService, - DiscordMemberFinderUtil discordMemberFinderUtil) { + DiscordMemberFinderUtil discordMemberFinderUtil, + AccessService accessService) { this.eventWaiter = eventWaiter; this.guildRoleService = guildRoleService; this.discordMemberFinderUtil = discordMemberFinderUtil; + this.accessService = accessService; } @Override @@ -45,7 +53,14 @@ public class RoleAssignListener implements Listener { discordMemberFinderUtil.onMemberFoundVerification(event, embedBuilder, privateChannel, member -> { embedBuilder.clearFields(); embedBuilder.setTitle("Type the numbers of the roles to add separated by a whitespace. If the member already has any role, it will get removed instead."); - var rolesToAdd = guildRoleService.findAllByElevationGreaterThanEqual(Constants.ADDED_ROLE_ELEVATION).stream() + Stream<Role> roleStream = event.getMember().getRoles().stream(); + var roleElevation = Constants.ADDED_ROLE_ELEVATION; + try { + accessService.isAllowed(roleStream, event, SUB_ADMIN); + } catch (InsufficientPrivilegesException e) { + roleElevation = Constants.ADDED_TEACHER_ROLE_ELEVATION; + } + var rolesToAdd = guildRoleService.findAllByElevationGreaterThanEqual(roleElevation).stream() .sorted(Comparator.nullsLast(Comparator.comparing(GuildRole::getOrderValue))) .toList(); for (GuildRole guildRole : rolesToAdd) { diff --git a/src/main/java/com/wimdupont/sxcybot/services/AccessService.java b/src/main/java/com/wimdupont/sxcybot/services/AccessService.java @@ -0,0 +1,43 @@ +package com.wimdupont.sxcybot.services; + +import com.wimdupont.sxcybot.exceptions.InsufficientPrivilegesException; +import com.wimdupont.sxcybot.repository.guild.dao.GuildRole; +import com.wimdupont.sxcybot.services.guild.GuildRoleService; +import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.entities.Role; +import net.dv8tion.jda.api.events.message.MessageReceivedEvent; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.function.Predicate; +import java.util.stream.Stream; + +@Service +public class AccessService { + + private final GuildRoleService guildRoleService; + + public AccessService(GuildRoleService guildRoleService) { + this.guildRoleService = guildRoleService; + } + + public void isAllowed(Stream<Role> roleStream, MessageReceivedEvent event, int elevation) + throws InsufficientPrivilegesException { + var guildRoles = guildRoleService.findAllByElevationLessThanEqual(elevation); + if (roleStream.noneMatch(hasPrivilege(event, guildRoles))) + throw new InsufficientPrivilegesException(guildRoles.stream() + .map(GuildRole::getDiscordId) + .flatMap(discordId -> event.getGuild().getRoles().stream() + .filter(f -> f.getId().equals(discordId))) + .map(Role::getName) + .toList()); + } + + private Predicate<Role> hasPrivilege(MessageReceivedEvent event, List<GuildRole> guildRoles) { + return f -> f.hasPermission(Permission.ADMINISTRATOR) + || (event.getMember() != null && event.getMember().isOwner()) + || guildRoles.stream() + .map(GuildRole::getDiscordId) + .anyMatch(e -> e.equalsIgnoreCase(f.getId())); + } +} diff --git a/src/main/java/com/wimdupont/sxcybot/util/Constants.java b/src/main/java/com/wimdupont/sxcybot/util/Constants.java @@ -7,6 +7,7 @@ public class Constants { } public static final int ADDED_ROLE_ELEVATION = 100; + public static final int ADDED_TEACHER_ROLE_ELEVATION = 120; public static class Commands { private Commands() { @@ -36,4 +37,17 @@ public class Constants { public static final String CHECK_MARK_BUTTON = "U+2705"; public static final String CROSS_MARK_BUTTON = "U+274E"; } + + public static class ROLE_ACCESS { + + private ROLE_ACCESS() { + } + + public static final int GOD = 0; + public static final int ADMIN_ROLE = 1; + public static final int GENERAL = 3; + public static final int SUB_ADMIN = 5; + public static final int STAFF_ROLE = 10; + public static final int TEACHER = 20; + } }