From e34ea795722bc7bbd23cb7a26c6088cf4e90c0a7 Mon Sep 17 00:00:00 2001 From: ION606 Date: Mon, 7 Apr 2025 14:21:04 -0400 Subject: [PATCH] added role check --- Bot/Commands/reactionrole.go | 56 ++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/Bot/Commands/reactionrole.go b/Bot/Commands/reactionrole.go index bf93210..fb65a98 100644 --- a/Bot/Commands/reactionrole.go +++ b/Bot/Commands/reactionrole.go @@ -9,10 +9,18 @@ import ( "github.com/bwmarrin/discordgo" ) +// Convert the manage roles permission into an int64 pointer for command registration. +func manageRolesPerm() *int64 { + p := int64(discordgo.PermissionManageRoles) + return &p +} + // ReactionRoleCommand defines the reaction role slash command with options for count and style. +// Only members with the "Manage Roles" permission may use this command. var ReactionRoleCommand = &discordgo.ApplicationCommand{ - Name: "reactionrole", - Description: "Setup a reaction role message using buttons. Provide a number (max 10) for role-button pairs.", + Name: "reactionrole", + Description: "Setup a reaction role message using buttons. Provide a number (max 10) for role-button pairs.", + DefaultMemberPermissions: manageRolesPerm(), Options: []*discordgo.ApplicationCommandOption{ { Type: discordgo.ApplicationCommandOptionInteger, @@ -65,9 +73,47 @@ func mapStyle(style string) discordgo.ButtonStyle { } } +// memberHasManageRoles checks if the given member has the Manage Roles permission. +func memberHasManageRoles(s *discordgo.Session, guildID string, member *discordgo.Member) (bool, error) { + roles, err := s.GuildRoles(guildID) + if err != nil { + return false, err + } + var perms int64 = 0 + for _, roleID := range member.Roles { + for _, role := range roles { + if role.ID == roleID { + perms |= int64(role.Permissions) + } + } + } + return perms&discordgo.PermissionManageRoles != 0, nil +} + // HandleReactionRole shows a modal with inputs for each role/button pair. -// It appends the chosen style to the modal's custom ID so that it is available during modal submit. +// It verifies that the invoking member has the Manage Roles permission. func HandleReactionRole(s *discordgo.Session, i *discordgo.InteractionCreate) { + // Check that the invoking member has the Manage Roles permission. + if i.GuildID == "" || i.Member == nil { + helpers.HandleError(s, i, fmt.Errorf("command must be used in a guild")) + return + } + hasPerm, err := memberHasManageRoles(s, i.GuildID, i.Member) + if err != nil { + helpers.HandleError(s, i, fmt.Errorf("failed to check user permissions: %w", err)) + return + } + if !hasPerm { + s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ + Type: discordgo.InteractionResponseChannelMessageWithSource, + Data: &discordgo.InteractionResponseData{ + Content: "Error: You need the Manage Roles permission to use this command.", + Flags: discordgo.MessageFlagsEphemeral, + }, + }) + return + } + options := i.ApplicationCommandData().Options count := int(options[0].IntValue()) @@ -117,7 +163,7 @@ func HandleReactionRole(s *discordgo.Session, i *discordgo.InteractionCreate) { Components: modalComponents, } - err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ + err = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ Type: discordgo.InteractionResponseModal, Data: modalData, }) @@ -299,7 +345,7 @@ func HandleReactionRoleButton(s *discordgo.Session, i *discordgo.InteractionCrea helpers.HandleError(s, i, fmt.Errorf("failed to check bot permissions: %w", err)) return } - + if !hasPerm { s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ Type: discordgo.InteractionResponseChannelMessageWithSource,