From c155effded563409e91c65a970bbb84dba586e44 Mon Sep 17 00:00:00 2001 From: rxdn <29165304+rxdn@users.noreply.github.com> Date: Tue, 26 Jul 2022 15:15:05 +0100 Subject: [PATCH] Overhaul blacklist --- app/http/endpoints/api/blacklist/blacklist.go | 112 +++-- .../endpoints/api/blacklist/blacklistadd.go | 126 ++++-- .../api/blacklist/blacklistremoverole.go | 25 + ...cklistremove.go => blacklistremoveuser.go} | 22 +- app/http/server.go | 5 +- .../src/components/ConfirmationModal.svelte | 1 - frontend/src/views/Blacklist.svelte | 428 ++++++++++++++---- go.mod | 5 + 8 files changed, 569 insertions(+), 155 deletions(-) create mode 100644 app/http/endpoints/api/blacklist/blacklistremoverole.go rename app/http/endpoints/api/blacklist/{blacklistremove.go => blacklistremoveuser.go} (52%) diff --git a/app/http/endpoints/api/blacklist/blacklist.go b/app/http/endpoints/api/blacklist/blacklist.go index 483afef..f74b502 100644 --- a/app/http/endpoints/api/blacklist/blacklist.go +++ b/app/http/endpoints/api/blacklist/blacklist.go @@ -1,56 +1,104 @@ package api import ( - "context" "github.com/TicketsBot/GoPanel/database" "github.com/TicketsBot/GoPanel/rpc/cache" "github.com/TicketsBot/GoPanel/utils" "github.com/gin-gonic/gin" "github.com/rxdn/gdl/objects/user" - "golang.org/x/sync/errgroup" + "strconv" ) -type userData struct { - UserId uint64 `json:"id,string"` - Username string `json:"username"` - Discriminator user.Discriminator `json:"discriminator"` -} +type ( + response struct { + PageLimit int `json:"page_limit"` + Users []blacklistedUser `json:"users"` + Roles []blacklistedRole `json:"roles"` + } + + blacklistedUser struct { + UserId uint64 `json:"id,string"` + Username string `json:"username"` + Discriminator user.Discriminator `json:"discriminator"` + } + + blacklistedRole struct { + RoleId uint64 `json:"id,string"` + Name string `json:"name"` + } +) + +const pageLimit = 30 // TODO: Paginate func GetBlacklistHandler(ctx *gin.Context) { guildId := ctx.Keys["guildid"].(uint64) - blacklistedUsers, err := database.Client.Blacklist.GetBlacklistedUsers(guildId) + page, err := strconv.Atoi(ctx.Query("page")) + if err != nil || page < 1 { + page = 1 + } + + offset := pageLimit * (page - 1) + + blacklistedUsers, err := database.Client.Blacklist.GetBlacklistedUsers(guildId, pageLimit, offset) if err != nil { ctx.JSON(500, utils.ErrorJson(err)) return } - data := make([]userData, len(blacklistedUsers)) - - group, _ := errgroup.WithContext(context.Background()) - for i, userId := range blacklistedUsers { - i := i - userId := userId - - // TODO: Mass lookup - group.Go(func() error { - userData := userData{ - UserId: userId, - } - - user, ok := cache.Instance.GetUser(userId) - if ok { - userData.Username = user.Username - userData.Discriminator = user.Discriminator - } - - data[i] = userData - return nil - }) + userObjects, err := cache.Instance.GetUsers(blacklistedUsers) + if err != nil { + ctx.JSON(500, utils.ErrorJson(err)) + return } - _ = group.Wait() + // Build struct with user_id, name and discriminator + users := make([]blacklistedUser, len(blacklistedUsers)) + for i, userId := range blacklistedUsers { + userData := blacklistedUser{ + UserId: userId, + } - ctx.JSON(200, data) + user, ok := userObjects[userId] + if ok { + userData.Username = user.Username + userData.Discriminator = user.Discriminator + } + + users[i] = userData + } + + blacklistedRoles, err := database.Client.RoleBlacklist.GetBlacklistedRoles(guildId) + if err != nil { + ctx.JSON(500, utils.ErrorJson(err)) + return + } + + roleObjects, err := cache.Instance.GetRoles(guildId, blacklistedRoles) + if err != nil { + ctx.JSON(500, utils.ErrorJson(err)) + return + } + + // Build struct with role_id and name + roles := make([]blacklistedRole, len(blacklistedRoles)) + for i, roleId := range blacklistedRoles { + roleData := blacklistedRole{ + RoleId: roleId, + } + + role, ok := roleObjects[roleId] + if ok { + roleData.Name = role.Name + } + + roles[i] = roleData + } + + ctx.JSON(200, response{ + PageLimit: pageLimit, + Users: users, + Roles: roles, + }) } diff --git a/app/http/endpoints/api/blacklist/blacklistadd.go b/app/http/endpoints/api/blacklist/blacklistadd.go index b0ee162..17974c2 100644 --- a/app/http/endpoints/api/blacklist/blacklistadd.go +++ b/app/http/endpoints/api/blacklist/blacklistadd.go @@ -1,49 +1,115 @@ package api import ( + "fmt" "github.com/TicketsBot/GoPanel/database" + "github.com/TicketsBot/GoPanel/rpc/cache" "github.com/TicketsBot/GoPanel/utils" "github.com/TicketsBot/common/permission" "github.com/gin-gonic/gin" - "strconv" +) + +type ( + blacklistAddResponse struct { + Success bool `json:"success"` + Resolved bool `json:"resolved"` + Id uint64 `json:"id,string"` + Username string `json:"username"` + Discriminator string `json:"discriminator"` + } + + blacklistAddBody struct { + EntityType entityType `json:"entity_type"` + Snowflake uint64 `json:"snowflake,string"` + } + + entityType int +) + +const ( + entityTypeUser entityType = iota + entityTypeRole ) func AddBlacklistHandler(ctx *gin.Context) { guildId := ctx.Keys["guildid"].(uint64) - id, err := strconv.ParseUint(ctx.Param("user"), 10, 64) - if err != nil { + var body blacklistAddBody + if err := ctx.BindJSON(&body); err != nil { ctx.JSON(400, utils.ErrorJson(err)) return } - // Max of 250 blacklisted users - count, err := database.Client.Blacklist.GetBlacklistedCount(guildId) - if err != nil { - ctx.JSON(500, utils.ErrorJson(err)) + if body.EntityType == entityTypeUser { + // Max of 250 blacklisted users + count, err := database.Client.Blacklist.GetBlacklistedCount(guildId) + if err != nil { + ctx.JSON(500, utils.ErrorJson(err)) + return + } + + if count >= 250 { + ctx.JSON(400, utils.ErrorStr("Blacklist limit (250) reached: consider using a role instead")) + return + } + + permLevel, err := utils.GetPermissionLevel(guildId, body.Snowflake) + if err != nil { + ctx.JSON(500, utils.ErrorJson(err)) + return + } + + if permLevel > permission.Everyone { + ctx.JSON(400, utils.ErrorStr("You cannot blacklist staff members!")) + return + } + + if err := database.Client.Blacklist.Add(guildId, body.Snowflake); err != nil { + ctx.JSON(500, utils.ErrorJson(err)) + return + } + + // Resolve user + user, ok := cache.Instance.GetUser(body.Snowflake) + if ok { + ctx.JSON(200, blacklistAddResponse{ + Success: true, + Resolved: true, + Id: body.Snowflake, + Username: user.Username, + Discriminator: fmt.Sprintf("%04d", user.Discriminator), + }) + } else { + ctx.JSON(200, blacklistAddResponse{ + Success: true, + Resolved: false, + Id: body.Snowflake, + }) + } + } else if body.EntityType == entityTypeRole { + // Max of 50 blacklisted roles + count, err := database.Client.RoleBlacklist.GetBlacklistedCount(guildId) + if err != nil { + ctx.JSON(500, utils.ErrorJson(err)) + return + } + + if count >= 50 { + ctx.JSON(400, utils.ErrorStr("Blacklist limit (50) reached")) + return + } + + if err := database.Client.RoleBlacklist.Add(guildId, body.Snowflake); err != nil { + ctx.JSON(500, utils.ErrorJson(err)) + return + } + + ctx.JSON(200, blacklistAddResponse{ + Success: true, + Id: body.Snowflake, + }) + } else { + ctx.JSON(400, utils.ErrorStr("Invalid entity type")) return } - - if count >= 250 { - ctx.JSON(400, utils.ErrorStr("Blacklist limit (250) reached: consider using a role instead")) - return - } - - permLevel, err := utils.GetPermissionLevel(guildId, id) - if err != nil { - ctx.JSON(500, utils.ErrorJson(err)) - return - } - - if permLevel > permission.Everyone { - ctx.JSON(400, utils.ErrorStr("You cannot blacklist staff members!")) - return - } - - if err = database.Client.Blacklist.Add(guildId, id); err != nil { - ctx.JSON(500, utils.ErrorJson(err)) - return - } - - ctx.JSON(200, utils.SuccessResponse) } diff --git a/app/http/endpoints/api/blacklist/blacklistremoverole.go b/app/http/endpoints/api/blacklist/blacklistremoverole.go new file mode 100644 index 0000000..3180214 --- /dev/null +++ b/app/http/endpoints/api/blacklist/blacklistremoverole.go @@ -0,0 +1,25 @@ +package api + +import ( + "github.com/TicketsBot/GoPanel/database" + "github.com/TicketsBot/GoPanel/utils" + "github.com/gin-gonic/gin" + "strconv" +) + +func RemoveRoleBlacklistHandler(ctx *gin.Context) { + guildId := ctx.Keys["guildid"].(uint64) + + roleId, err := strconv.ParseUint(ctx.Param("role"), 10, 64) + if err != nil { + ctx.JSON(400, utils.ErrorJson(err)) + return + } + + if err := database.Client.RoleBlacklist.Remove(guildId, roleId); err != nil { + ctx.JSON(500, utils.ErrorJson(err)) + return + } + + ctx.Status(204) +} diff --git a/app/http/endpoints/api/blacklist/blacklistremove.go b/app/http/endpoints/api/blacklist/blacklistremoveuser.go similarity index 52% rename from app/http/endpoints/api/blacklist/blacklistremove.go rename to app/http/endpoints/api/blacklist/blacklistremoveuser.go index 02cf0c0..c203fe7 100644 --- a/app/http/endpoints/api/blacklist/blacklistremove.go +++ b/app/http/endpoints/api/blacklist/blacklistremoveuser.go @@ -2,30 +2,24 @@ package api import ( "github.com/TicketsBot/GoPanel/database" + "github.com/TicketsBot/GoPanel/utils" "github.com/gin-gonic/gin" "strconv" ) -func RemoveBlacklistHandler(ctx *gin.Context) { +func RemoveUserBlacklistHandler(ctx *gin.Context) { guildId := ctx.Keys["guildid"].(uint64) userId, err := strconv.ParseUint(ctx.Param("user"), 10, 64) if err != nil { - ctx.AbortWithStatusJSON(400, gin.H{ - "success": false, - "error": err.Error(), - }) + ctx.JSON(400, utils.ErrorJson(err)) return } - if err := database.Client.Blacklist.Remove(guildId, userId); err == nil { - ctx.JSON(200, gin.H{ - "success": true, - }) - } else { - ctx.JSON(200, gin.H{ - "success": false, - "err": err.Error(), - }) + if err := database.Client.Blacklist.Remove(guildId, userId); err != nil { + ctx.JSON(500, utils.ErrorJson(err)) + return } + + ctx.Status(204) } diff --git a/app/http/server.go b/app/http/server.go index b93c04b..9d775a7 100644 --- a/app/http/server.go +++ b/app/http/server.go @@ -100,8 +100,9 @@ func StartServer() { guildAuthApiAdmin.POST("/settings", api_settings.UpdateSettingsHandler) guildAuthApiSupport.GET("/blacklist", api_blacklist.GetBlacklistHandler) - guildAuthApiSupport.POST("/blacklist/:user", api_blacklist.AddBlacklistHandler) - guildAuthApiSupport.DELETE("/blacklist/:user", api_blacklist.RemoveBlacklistHandler) + guildAuthApiSupport.POST("/blacklist", api_blacklist.AddBlacklistHandler) + guildAuthApiSupport.DELETE("/blacklist/user/:user", api_blacklist.RemoveUserBlacklistHandler) + guildAuthApiSupport.DELETE("/blacklist/role/:role", api_blacklist.RemoveRoleBlacklistHandler) // Must be readable to load transcripts page guildAuthApiSupport.GET("/panels", api_panels.ListPanels) diff --git a/frontend/src/components/ConfirmationModal.svelte b/frontend/src/components/ConfirmationModal.svelte index c291971..7fcccda 100644 --- a/frontend/src/components/ConfirmationModal.svelte +++ b/frontend/src/components/ConfirmationModal.svelte @@ -34,7 +34,6 @@ diff --git a/go.mod b/go.mod index a15bd1a..7d45097 100644 --- a/go.mod +++ b/go.mod @@ -83,3 +83,8 @@ require ( gopkg.in/yaml.v2 v2.4.0 // indirect nhooyr.io/websocket v1.8.4 // indirect ) + +replace ( + github.com/rxdn/gdl => "../../rxdn/gdl" + github.com/TicketsBot/database => "../database" +)