From 357355b18ec20ff0d899af8bfb719a3902eccf3e Mon Sep 17 00:00:00 2001 From: vaporvee Date: Sun, 14 Apr 2024 02:46:34 +0200 Subject: [PATCH] set permission requirements for more commands --- cmd_addemoji.go | 6 ++-- cmd_autopublish.go | 6 ++-- cmd_blockpolls.go | 81 +++++++++++++++++++++++++++++++++++-------- handlers.go | 8 ++++- manage_data.go | 85 ++++++++++++++++++++++++++++++++++++++-------- 5 files changed, 151 insertions(+), 35 deletions(-) diff --git a/cmd_addemoji.go b/cmd_addemoji.go index eb1901e..1733a7c 100644 --- a/cmd_addemoji.go +++ b/cmd_addemoji.go @@ -9,13 +9,15 @@ import ( "github.com/disgoorg/disgo/discord" "github.com/disgoorg/disgo/events" + "github.com/disgoorg/json" "github.com/sirupsen/logrus" ) var cmd_addemoji Command = Command{ Definition: discord.SlashCommandCreate{ - Name: "add-emoji", - Description: "Add an external emoji directly to the server.", + Name: "add-emoji", + Description: "Add an external emoji directly to the server.", + DefaultMemberPermissions: json.NewNullablePtr(discord.PermissionManageGuildExpressions), Options: []discord.ApplicationCommandOption{ &discord.ApplicationCommandOptionString{ Name: "emoji", diff --git a/cmd_autopublish.go b/cmd_autopublish.go index 35ee438..0c6b408 100644 --- a/cmd_autopublish.go +++ b/cmd_autopublish.go @@ -3,13 +3,15 @@ package main import ( "github.com/disgoorg/disgo/discord" "github.com/disgoorg/disgo/events" + "github.com/disgoorg/json" "github.com/sirupsen/logrus" ) var cmd_autopublish Command = Command{ Definition: discord.SlashCommandCreate{ - Name: "autopublish", - Description: "Toggle automatically publishing every post in a announcement channel", + Name: "autopublish", + Description: "Toggle automatically publishing every post in a announcement channel", + DefaultMemberPermissions: json.NewNullablePtr(discord.PermissionManageChannels), Contexts: []discord.InteractionContextType{ discord.InteractionContextTypeGuild, discord.InteractionContextTypePrivateChannel}, diff --git a/cmd_blockpolls.go b/cmd_blockpolls.go index 21b8b52..32e1c68 100644 --- a/cmd_blockpolls.go +++ b/cmd_blockpolls.go @@ -3,34 +3,85 @@ package main import ( "github.com/disgoorg/disgo/discord" "github.com/disgoorg/disgo/events" + "github.com/disgoorg/json" "github.com/sirupsen/logrus" ) var cmd_blockpolls Command = Command{ Definition: discord.SlashCommandCreate{ - Name: "block-polls", - Description: "Toggle blocking polls from beeing posted in this channel.", + Name: "block-polls", + Description: "Block polls from beeing posted in this channel.", + DefaultMemberPermissions: json.NewNullablePtr(discord.PermissionManageChannels), Contexts: []discord.InteractionContextType{ discord.InteractionContextTypeGuild, discord.InteractionContextTypePrivateChannel}, IntegrationTypes: []discord.ApplicationIntegrationType{ discord.ApplicationIntegrationTypeGuildInstall}, + Options: []discord.ApplicationCommandOption{ + &discord.ApplicationCommandOptionSubCommand{ + Name: "toggle", + Description: "Toggle blocking polls from beeing posted in this channel.", + Options: []discord.ApplicationCommandOption{ + &discord.ApplicationCommandOptionBool{ + Name: "global", + Description: "If polls are blocked server wide or only in the current channel.", + }, + &discord.ApplicationCommandOptionRole{ + Name: "allowed-role", + Description: "The role that bypasses this block role.", + }, + }, + }, + /*&discord.ApplicationCommandOptionSubCommand{ + Name: "list", + Description: "List the current block polls rules for this server.", + },*/ + }, }, Interact: func(e *events.ApplicationCommandInteractionCreate) { - if toggleBlockPolls(e.GuildID().String(), e.Channel().ID().String()) { - err := e.CreateMessage(discord.NewMessageCreateBuilder(). - SetContent("Polls are now unblocked in " + discord.ChannelMention(e.Channel().ID())).SetEphemeral(true). - Build()) - if err != nil { - logrus.Error(err) - } - } else { - err := e.CreateMessage(discord.NewMessageCreateBuilder(). - SetContent("Polls are now blocked in " + discord.ChannelMention(e.Channel().ID())).SetEphemeral(true). - Build()) - if err != nil { - logrus.Error(err) + switch *e.SlashCommandInteractionData().SubCommandName { + case "toggle": + isGlobal := isGlobalBlockPolls(e.GuildID().String()) + if isGlobal && !e.SlashCommandInteractionData().Bool("global") { + e.CreateMessage(discord.NewMessageCreateBuilder().SetContent("Polls are currently globally blocked. Disable global blocking to enable channel specific blocking.").SetEphemeral(true).Build()) + } else { + exists, isGlobal := toggleBlockPolls(e.GuildID().String(), e.Channel().ID().String(), e.SlashCommandInteractionData().Bool("global"), e.SlashCommandInteractionData().Role("allowed-role").ID.String()) + if exists { + if e.SlashCommandInteractionData().Bool("global") { + err := e.CreateMessage(discord.NewMessageCreateBuilder(). + SetContent("Polls are now globally unblocked.").SetEphemeral(true). + Build()) + if err != nil { + logrus.Error(err) + } + } else { + err := e.CreateMessage(discord.NewMessageCreateBuilder(). + SetContent("Polls are now unblocked in " + discord.ChannelMention(e.Channel().ID())).SetEphemeral(true). + Build()) + if err != nil { + logrus.Error(err) + } + } + } else { + if isGlobal { + err := e.CreateMessage(discord.NewMessageCreateBuilder(). + SetContent("Polls are now globally blocked.").SetEphemeral(true). + Build()) + if err != nil { + logrus.Error(err) + } + } else { + err := e.CreateMessage(discord.NewMessageCreateBuilder(). + SetContent("Polls are now blocked in " + discord.ChannelMention(e.Channel().ID())).SetEphemeral(true). + Build()) + if err != nil { + logrus.Error(err) + } + } + } } + /*case "list": + list := listBlockPolls(e.GuildID().String())*/ } }, } diff --git a/handlers.go b/handlers.go index 0c0bedb..c729bab 100644 --- a/handlers.go +++ b/handlers.go @@ -171,7 +171,13 @@ func messageCreate(e *events.MessageCreate) { logrus.Error(err) } if channel != nil { - if isBlockPollsEnabled(e.GuildID.String(), e.Message.ChannelID.String()) && messageIsPoll(e.Message.ChannelID.String(), e.Message.ID.String(), e.Client()) { + isBlockPollsEnabledGlobal := isGlobalBlockPolls(e.GuildID.String()) + isBlockPollsEnabled, allowedRole := getBlockPollsEnabled(e.GuildID.String(), e.Message.ChannelID.String()) + var hasAllowedRole bool + if allowedRole != "" { + hasAllowedRole = slices.Contains(e.Message.Member.RoleIDs, snowflake.MustParse(allowedRole)) + } + if (isBlockPollsEnabledGlobal || isBlockPollsEnabled) && !hasAllowedRole && messageIsPoll(e.Message.ChannelID.String(), e.Message.ID.String(), e.Client()) { e.Client().Rest().DeleteMessage(e.Message.ChannelID, e.Message.ID) } if channel.Type() == discord.ChannelTypeGuildNews { diff --git a/manage_data.go b/manage_data.go index 1fa2f07..b07136d 100644 --- a/manage_data.go +++ b/manage_data.go @@ -57,8 +57,10 @@ func initTables() { ); CREATE TABLE IF NOT EXISTS blockpolls ( guild_id TEXT NOT NULL, - channel_id TEXT NOT NULL, - PRIMARY KEY (guild_id, channel_id) + channel_id TEXT, + global BOOLEAN, + allowed_role TEXT, + PRIMARY KEY (guild_id) ) ` _, err := db.Exec(createTableQuery) @@ -66,15 +68,11 @@ func initTables() { log.Fatal(err) } if slices.Contains(os.Args, "--form-db-update") { - _, err := db.Exec("ALTER TABLE form_manage ADD moderator_id TEXT;") + _, err = db.Exec("ALTER TABLE blockpolls ADD global BOOLEAN;") if err != nil { log.Fatal(err) } - _, err = db.Exec("ALTER TABLE form_manage ADD comment_category TEXT;") - if err != nil { - log.Fatal(err) - } - _, err = db.Exec("ALTER TABLE form_manage DROP COLUMN mods_can_comment;") + _, err = db.Exec("ALTER TABLE blockpolls ADD allowed_role TEXT;") if err != nil { log.Fatal(err) } @@ -89,6 +87,12 @@ type FormResult struct { ModeratorID string } +type BlockPoll struct { + ChannelID string + Global bool + AllowedRole string +} + func addTag(guildID, tagName, tagContent string) bool { var exists bool = true //TODO: add modify command @@ -400,33 +404,84 @@ func isAutopublishEnabled(guildID string, newsChannelID string) bool { return enabled } -func toggleBlockPolls(guildID string, channelID string) bool { +func isGlobalBlockPolls(guildID string) bool { + var globalexists bool + err := db.QueryRow("SELECT EXISTS (SELECT 1 FROM blockpolls WHERE guild_id = $1 AND global = true)", guildID).Scan(&globalexists) + if err != nil { + logrus.Error(err) + } + return globalexists +} + +func toggleBlockPolls(guildID string, channelID string, global bool, allowedRole string) (e bool, isGlobal bool) { + globalexists := isGlobalBlockPolls(guildID) var exists bool err := db.QueryRow("SELECT EXISTS (SELECT 1 FROM blockpolls WHERE guild_id = $1 AND channel_id = $2)", guildID, channelID).Scan(&exists) if err != nil { logrus.Error(err) } - if exists { + if globalexists { + _, err := db.Exec("DELETE FROM blockpolls WHERE guild_id = $1 AND global = true", guildID) + if err != nil { + logrus.Error(err) + } + return true, true + } else if global { + _, err = db.Exec("DELETE FROM blockpolls WHERE guild_id = $1", guildID) + if err != nil { + logrus.Error(err) + } + _, err := db.Exec("INSERT INTO blockpolls (guild_id, global, channel_id, allowed_role) VALUES ($1, true, $2, $3)", guildID, channelID, allowedRole) + if err != nil { + logrus.Error(err) + } + return false, true + } else if exists && !globalexists { _, err := db.Exec("DELETE FROM blockpolls WHERE guild_id = $1 AND channel_id = $2", guildID, channelID) if err != nil { logrus.Error(err) } - } else { - _, err := db.Exec("INSERT INTO blockpolls (guild_id, channel_id) VALUES ($1, $2)", guildID, channelID) + return true, false + } else if !globalexists { + _, err := db.Exec("INSERT INTO blockpolls (guild_id, channel_id, allowed_role) VALUES ($1, $2, $3)", guildID, channelID, allowedRole) if err != nil { logrus.Error(err) } + return false, false + } else { + return false, false } - return exists } -func isBlockPollsEnabled(guildID string, channelID string) bool { +func listBlockPolls(guildID string) []BlockPoll { + var list []BlockPoll + rows, err := db.Query("SELECT channel_id, global, allowed_role FROM blockpolls WHERE guild_id = $1", guildID) + if err != nil { + log.Fatal(err) + } + for rows.Next() { + var bp BlockPoll + err := rows.Scan(&bp.ChannelID, &bp.Global, &bp.AllowedRole) + if err != nil { + log.Fatal(err) + } + list = append(list, bp) + } + return list +} + +func getBlockPollsEnabled(guildID string, channelID string) (isEnabled bool, allowedRole string) { var enabled bool + var v_allowedRole string err := db.QueryRow("SELECT EXISTS (SELECT 1 FROM blockpolls WHERE guild_id = $1 AND channel_id = $2)", guildID, channelID).Scan(&enabled) if err != nil { logrus.Error(err) } - return enabled + err = db.QueryRow("SELECT allowed_role FROM blockpolls WHERE guild_id = $1 AND channel_id = $2", guildID, channelID).Scan(&v_allowedRole) + if err != nil && err.Error() != "sql: no rows in result set" { + logrus.Error(err) + } + return enabled, v_allowedRole } func tryDeleteUnusedMessage(messageID string) {