Skip to content

Commit

Permalink
Permission List-All, Set, Get & Clear implementations, some goofy ref…
Browse files Browse the repository at this point in the history
…lection stuff
  • Loading branch information
jokil123 committed Jan 14, 2024
1 parent 214ee1a commit 7d86ff6
Show file tree
Hide file tree
Showing 15 changed files with 724 additions and 102 deletions.
259 changes: 242 additions & 17 deletions EsefexApi/bot/commands/permission.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package commands
import (
"esefexapi/permissions"
"esefexapi/types"
"esefexapi/util"
"esefexapi/util/refl"
"fmt"

"github.com/bwmarrin/discordgo"
Expand All @@ -29,8 +31,7 @@ var PermissionCommand = &discordgo.ApplicationCommand{
Description: "The permission to set.",
Type: discordgo.ApplicationCommandOptionString,
Required: true,
// TODO: Dynamically get the choices from the permission type on startup using reflection.
// Choices: []*discordgo.ApplicationCommandOptionChoice{}
Choices: getPathOptions(),
},
{
Name: "value",
Expand Down Expand Up @@ -70,8 +71,7 @@ var PermissionCommand = &discordgo.ApplicationCommand{
Description: "The permission to get.",
Type: discordgo.ApplicationCommandOptionString,
Required: true,
// TODO: Dynamically get the choices from the permission type on startup using reflection.
// Choices: []*discordgo.ApplicationCommandOptionChoice{}
Choices: getPathOptions(),
},
},
},
Expand Down Expand Up @@ -101,6 +101,11 @@ var PermissionCommand = &discordgo.ApplicationCommand{
},
},
},
{
Name: "list-all",
Description: "List all permissions for all users, channels and roles.",
Type: discordgo.ApplicationCommandOptionSubCommand,
},
},
}

Expand All @@ -114,52 +119,272 @@ func (c *CommandHandlers) Permission(s *discordgo.Session, i *discordgo.Interact
return c.PermissionClear(s, i)
case "list":
return c.PermissionList(s, i)
case "list-all":
return c.PermissionListAll(s, i)
default:
return nil, errors.Wrap(fmt.Errorf("Unknown subcommand %s", i.ApplicationCommandData().Options[0].Name), "Error handling user command")
}
}

// TODO: Fix the race condition that might occur here
func (c *CommandHandlers) PermissionSet(s *discordgo.Session, i *discordgo.InteractionCreate) (*discordgo.InteractionResponse, error) {
return nil, errors.Wrap(fmt.Errorf("Not implemented"), "Error handling user command PermissionSet")
id := fmt.Sprintf("%v", i.ApplicationCommandData().Options[0].Options[0].Value)
ty, err := extractTypeFromString(s, types.GuildID(i.GuildID), id)
if err != nil {
return nil, errors.Wrap(err, "Error extracting type from string")
}

p, err := getPermissions(s, c.dbs, types.GuildID(i.GuildID), id)
if err != nil {
return nil, errors.Wrap(err, "Error getting permissions")
}

ps := permissions.PSFromString(fmt.Sprintf("%v", i.ApplicationCommandData().Options[0].Options[2].Value))

ppath := fmt.Sprintf("%v", i.ApplicationCommandData().Options[0].Options[1].Value)

err = refl.SetNestedFieldValue(&p, ppath, ps)
if err != nil {
return nil, errors.Wrap(err, "Error setting nested field value")
}

switch ty.PermissionType {
case permissions.User:
err = c.dbs.PermissionDB.UpdateUser(types.UserID(ty.ID), p)
case permissions.Role:
err = c.dbs.PermissionDB.UpdateRole(types.RoleID(ty.ID), p)
case permissions.Channel:
err = c.dbs.PermissionDB.UpdateChannel(types.ChannelID(ty.ID), p)
}

if err != nil {
return nil, errors.Wrap(err, "Error setting permissions")
}

return &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Content: fmt.Sprintf("Set %s for %s to %s", ppath, id, ps.String()),
},
}, nil
}

func (c *CommandHandlers) PermissionGet(s *discordgo.Session, i *discordgo.InteractionCreate) (*discordgo.InteractionResponse, error) {
return nil, errors.Wrap(fmt.Errorf("Not implemented"), "Error handling user command PermissionGet")
// TODO: Better alignment for the list all command (maybe use a table?)
func (c *CommandHandlers) PermissionListAll(s *discordgo.Session, i *discordgo.InteractionCreate) (*discordgo.InteractionResponse, error) {
resp := "Permissions for all users, channels and roles:\n"

resp += "**Users**\n"
uids, err := c.dbs.PermissionDB.GetUsers()
if err != nil {
return nil, errors.Wrap(err, "Error getting users")
}
if len(uids) == 0 {
resp += "`No users found.`\n"
}
for _, uid := range uids {
p, err := getPermissions(s, c.dbs, types.GuildID(i.GuildID), uid.String())
if err != nil {
return nil, errors.Wrap(err, "Error getting permissions")
}

pstr, err := formatPermissionsCompact(p)
if err != nil {
return nil, errors.Wrap(err, "Error formatting permissions")
}

uname, err := util.UserIDName(s, uid)
if err != nil {
return nil, errors.Wrap(err, "Error getting user")
}

resp += fmt.Sprintf("%s: ", uname)
resp += pstr
resp += "\n"
}

resp += "**Roles**\n"
rids, err := c.dbs.PermissionDB.GetRoles()
if err != nil {
return nil, errors.Wrap(err, "Error getting roles")
}
if len(rids) == 0 {
resp += "`No roles found.`\n"
}
for _, rid := range rids {
p, err := getPermissions(s, c.dbs, types.GuildID(i.GuildID), rid.String())
if err != nil {
return nil, errors.Wrap(err, "Error getting permissions")
}

pstr, err := formatPermissionsCompact(p)
if err != nil {
return nil, errors.Wrap(err, "Error formatting permissions")
}

rmention, err := util.RoleIDName(s, types.GuildID(i.GuildID), rid)
if err != nil {
return nil, errors.Wrap(err, "Error getting role")
}

resp += fmt.Sprintf("%s: ", rmention)
resp += pstr
resp += "\n"
}

resp += "**Channels**\n"
cids, err := c.dbs.PermissionDB.GetChannels()
if err != nil {
return nil, errors.Wrap(err, "Error getting channels")
}
if len(cids) == 0 {
resp += "`No channels found.`\n"
}
for _, cid := range cids {
p, err := getPermissions(s, c.dbs, types.GuildID(i.GuildID), cid.String())
if err != nil {
return nil, errors.Wrap(err, "Error getting permissions")
}

pstr, err := formatPermissionsCompact(p)
if err != nil {
return nil, errors.Wrap(err, "Error formatting permissions")
}

cmention, err := util.ChannelIDMention(s, types.GuildID(i.GuildID), cid)
if err != nil {
return nil, errors.Wrap(err, "Error getting channel")
}

resp += fmt.Sprintf("%s: ", cmention)
resp += pstr
resp += "\n"
}

return &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Content: resp,
},
}, nil
}

func (c *CommandHandlers) PermissionClear(s *discordgo.Session, i *discordgo.InteractionCreate) (*discordgo.InteractionResponse, error) {
return nil, errors.Wrap(fmt.Errorf("Not implemented"), "Error handling user command PermissionClear")
func (c *CommandHandlers) PermissionGet(s *discordgo.Session, i *discordgo.InteractionCreate) (*discordgo.InteractionResponse, error) {
id := fmt.Sprintf("%v", i.ApplicationCommandData().Options[0].Options[0].Value)

p, err := getPermissions(s, c.dbs, types.GuildID(i.GuildID), id)
if err != nil {
return nil, errors.Wrap(err, "Error getting permissions")
}

ppath := fmt.Sprintf("%v", i.ApplicationCommandData().Options[0].Options[1].Value)

ps, err := getPermission(p, ppath)
if err != nil {
return nil, errors.Wrap(err, "Error getting permission")
}

ty, err := extractTypeFromString(s, types.GuildID(i.GuildID), id)
if err != nil {
return nil, errors.Wrap(err, "Error extracting type from string")
}

var name string
switch ty.PermissionType {
case permissions.User:
name, err = util.UserIDName(s, types.UserID(ty.ID))
case permissions.Role:
name, err = util.RoleIDName(s, types.GuildID(i.GuildID), types.RoleID(ty.ID))
case permissions.Channel:
name, err = util.ChannelIDMention(s, types.GuildID(i.GuildID), types.ChannelID(ty.ID))
}
if err != nil {
return nil, errors.Wrap(err, "Error getting name")
}

// TODO: add name display here
resp := fmt.Sprintf("%s for %s: %s", ppath, name, ps.String())
return &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Content: resp,
},
}, nil
}

func (c *CommandHandlers) PermissionList(s *discordgo.Session, i *discordgo.InteractionCreate) (*discordgo.InteractionResponse, error) {
// TODO: Fix this command (it is not clearing permissions)
func (c *CommandHandlers) PermissionClear(s *discordgo.Session, i *discordgo.InteractionCreate) (*discordgo.InteractionResponse, error) {
id := fmt.Sprintf("%v", i.ApplicationCommandData().Options[0].Options[0].Value)
ty, err := extractTypeFromString(s, types.GuildID(i.GuildID), id)
if err != nil {
return nil, errors.Wrap(err, "Error extracting type from string")
}

var p permissions.Permissions
var name string
switch ty.PermissionType {
case permissions.User:
name, err = util.UserIDName(s, types.UserID(ty.ID))
case permissions.Role:
name, err = util.RoleIDName(s, types.GuildID(i.GuildID), types.RoleID(ty.ID))
case permissions.Channel:
name, err = util.ChannelIDMention(s, types.GuildID(i.GuildID), types.ChannelID(ty.ID))
}
if err != nil {
return nil, errors.Wrap(err, "Error getting name")
}

switch ty.PermissionType {
case permissions.User:
p, err = c.dbs.PremissionDB.GetUser(types.UserID(ty.ID))
err = c.dbs.PermissionDB.UpdateUser(types.UserID(ty.ID), permissions.NewUnset())
case permissions.Role:
p, err = c.dbs.PremissionDB.GetRole(types.RoleID(ty.ID))
err = c.dbs.PermissionDB.UpdateRole(types.RoleID(ty.ID), permissions.NewUnset())
case permissions.Channel:
p, err = c.dbs.PremissionDB.GetChannel(types.ChannelID(ty.ID))
err = c.dbs.PermissionDB.UpdateChannel(types.ChannelID(ty.ID), permissions.NewUnset())
}
if err != nil {
return nil, errors.Wrap(err, "Error clearing permissions")
}

return &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Content: fmt.Sprintf("Cleared permissions for %s %s", ty.PermissionType, name),
},
}, nil
}

func (c *CommandHandlers) PermissionList(s *discordgo.Session, i *discordgo.InteractionCreate) (*discordgo.InteractionResponse, error) {
id := fmt.Sprintf("%v", i.ApplicationCommandData().Options[0].Options[0].Value)

p, err := getPermissions(s, c.dbs, types.GuildID(i.GuildID), id)
if err != nil {
return nil, errors.Wrap(err, "Error getting permissions")
}

ps, err := formatPermissions(p)
pstr, err := formatPermissions(p)
if err != nil {
return nil, errors.Wrap(err, "Error formatting permissions")
}

resp := fmt.Sprintf("Permissions for %s %s:\n", ty.PermissionType, ty.ID)
resp += ps
ty, err := extractTypeFromString(s, types.GuildID(i.GuildID), id)
if err != nil {
return nil, errors.Wrap(err, "Error extracting type from string")
}

var name string
switch ty.PermissionType {
case permissions.User:
name, err = util.UserIDName(s, types.UserID(ty.ID))
case permissions.Role:
name, err = util.RoleIDName(s, types.GuildID(i.GuildID), types.RoleID(ty.ID))
case permissions.Channel:
name, err = util.ChannelIDMention(s, types.GuildID(i.GuildID), types.ChannelID(ty.ID))
}
if err != nil {
return nil, errors.Wrap(err, "Error getting name")
}

resp := fmt.Sprintf("Permissions for %s:\n", name)
resp += pstr

return &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Expand Down
6 changes: 0 additions & 6 deletions EsefexApi/bot/commands/sound.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"log"

"github.com/bwmarrin/discordgo"
"github.com/davecgh/go-spew/spew"
"github.com/pkg/errors"
)

Expand Down Expand Up @@ -80,11 +79,6 @@ func (c *CommandHandlers) Sound(s *discordgo.Session, i *discordgo.InteractionCr
default:
return nil, errors.Wrap(fmt.Errorf("Unknown subcommand %s", i.ApplicationCommandData().Options[0].Name), "Error handling user command")
}

log.Println("User command called with options:")
spew.Dump(i.ApplicationCommandData().Options)

return nil, errors.Wrap(fmt.Errorf("Not implemented"), "Sound")
}

func (c *CommandHandlers) SoundUpload(s *discordgo.Session, i *discordgo.InteractionCreate) (*discordgo.InteractionResponse, error) {
Expand Down
Loading

0 comments on commit 7d86ff6

Please sign in to comment.