diff --git a/app/constants.go b/app/constants.go new file mode 100644 index 0000000..bbea89f --- /dev/null +++ b/app/constants.go @@ -0,0 +1,14 @@ +package app + +import ( + "context" + "time" +) + +// DefaultTimeout is the default timeout for operations requiring REST requests: this is a high value, as the HTTP proxy +// may delay requests to avoid rate limits. +const DefaultTimeout = time.Second * 30 + +func DefaultContext() (context.Context, context.CancelFunc) { + return context.WithTimeout(context.Background(), DefaultTimeout) +} diff --git a/app/http/endpoints/api/admin/botstaff/list.go b/app/http/endpoints/api/admin/botstaff/list.go index 4badd2a..d9919b9 100644 --- a/app/http/endpoints/api/admin/botstaff/list.go +++ b/app/http/endpoints/api/admin/botstaff/list.go @@ -2,10 +2,12 @@ package botstaff import ( "context" + "errors" "github.com/TicketsBot/GoPanel/database" "github.com/TicketsBot/GoPanel/rpc/cache" "github.com/TicketsBot/GoPanel/utils" "github.com/gin-gonic/gin" + cache2 "github.com/rxdn/gdl/cache" "github.com/rxdn/gdl/objects/user" "golang.org/x/sync/errgroup" ) @@ -32,17 +34,18 @@ func ListBotStaffHandler(ctx *gin.Context) { userId := userId group.Go(func() error { - user, ok := cache.Instance.GetUser(userId) - data := userData{ Id: userId, } - if ok { + user, err := cache.Instance.GetUser(context.Background(), userId) + if err == nil { data.Username = user.Username data.Discriminator = user.Discriminator - } else { + } else if errors.Is(err, cache2.ErrNotFound) { data.Username = "Unknown User" + } else { + return err } users[i] = data diff --git a/app/http/endpoints/api/blacklist/blacklist.go b/app/http/endpoints/api/blacklist/blacklist.go index be07d44..108cd8f 100644 --- a/app/http/endpoints/api/blacklist/blacklist.go +++ b/app/http/endpoints/api/blacklist/blacklist.go @@ -1,6 +1,7 @@ package api import ( + "context" "github.com/TicketsBot/GoPanel/database" "github.com/TicketsBot/GoPanel/rpc/cache" "github.com/TicketsBot/GoPanel/utils" @@ -41,7 +42,8 @@ func GetBlacklistHandler(ctx *gin.Context) { return } - userObjects, err := cache.Instance.GetUsers(blacklistedUsers) + // TODO: Use proper context + userObjects, err := cache.Instance.GetUsers(context.Background(), blacklistedUsers) if err != nil { ctx.JSON(500, utils.ErrorJson(err)) return diff --git a/app/http/endpoints/api/blacklist/blacklistadd.go b/app/http/endpoints/api/blacklist/blacklistadd.go index 0e938c4..c405f3b 100644 --- a/app/http/endpoints/api/blacklist/blacklistadd.go +++ b/app/http/endpoints/api/blacklist/blacklistadd.go @@ -1,11 +1,14 @@ package api import ( + "context" "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" + "github.com/pkg/errors" + cache2 "github.com/rxdn/gdl/cache" ) type ( @@ -51,7 +54,8 @@ func AddBlacklistHandler(ctx *gin.Context) { return } - permLevel, err := utils.GetPermissionLevel(guildId, body.Snowflake) + // TODO: Use proper context + permLevel, err := utils.GetPermissionLevel(context.Background(), guildId, body.Snowflake) if err != nil { ctx.JSON(500, utils.ErrorJson(err)) return @@ -68,21 +72,28 @@ func AddBlacklistHandler(ctx *gin.Context) { } // 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, - }) - } else { - ctx.JSON(200, blacklistAddResponse{ - Success: true, - Resolved: false, - Id: body.Snowflake, - }) + // TODO: Use proper context + user, err := cache.Instance.GetUser(context.Background(), body.Snowflake) + if err != nil { + if errors.Is(err, cache2.ErrNotFound) { + ctx.JSON(200, blacklistAddResponse{ + Success: true, + Resolved: false, + Id: body.Snowflake, + }) + return + } else { + ctx.JSON(500, utils.ErrorJson(err)) + return + } } + + ctx.JSON(200, blacklistAddResponse{ + Success: true, + Resolved: true, + Id: body.Snowflake, + Username: user.Username, + }) } else if body.EntityType == entityTypeRole { // Max of 50 blacklisted roles count, err := database.Client.RoleBlacklist.GetBlacklistedCount(guildId) diff --git a/app/http/endpoints/api/channels.go b/app/http/endpoints/api/channels.go index 4907fdc..2f1e83e 100644 --- a/app/http/endpoints/api/channels.go +++ b/app/http/endpoints/api/channels.go @@ -1,8 +1,12 @@ package api import ( + "context" + "errors" "github.com/TicketsBot/GoPanel/rpc/cache" + "github.com/TicketsBot/GoPanel/utils" "github.com/gin-gonic/gin" + cache2 "github.com/rxdn/gdl/cache" "github.com/rxdn/gdl/objects/channel" "sort" ) @@ -10,8 +14,20 @@ import ( func ChannelsHandler(ctx *gin.Context) { guildId := ctx.Keys["guildid"].(uint64) - var channels []channel.Channel - for _, ch := range cache.Instance.GetGuildChannels(guildId) { + // TODO: Use proper context + channels, err := cache.Instance.GetGuildChannels(context.Background(), guildId) + if err != nil { + if errors.Is(err, cache2.ErrNotFound) { + ctx.JSON(200, make([]channel.Channel, 0)) + } else { + ctx.JSON(500, utils.ErrorJson(err)) + } + + return + } + + filtered := make([]channel.Channel, 0, len(channels)) + for _, ch := range channels { // Filter out threads if ch.Type == channel.ChannelTypeGuildNewsThread || ch.Type == channel.ChannelTypeGuildPrivateThread || @@ -19,16 +35,12 @@ func ChannelsHandler(ctx *gin.Context) { continue } - channels = append(channels, ch) + filtered = append(filtered, ch) } - if channels == nil { - channels = make([]channel.Channel, 0) // don't serve null - } else { - sort.Slice(channels, func(i, j int) bool { - return channels[i].Position < channels[j].Position - }) - } + sort.Slice(filtered, func(i, j int) bool { + return filtered[i].Position < filtered[j].Position + }) - ctx.JSON(200, channels) + ctx.JSON(200, filtered) } diff --git a/app/http/endpoints/api/emojis.go b/app/http/endpoints/api/emojis.go index f6e7e85..6c16b1e 100644 --- a/app/http/endpoints/api/emojis.go +++ b/app/http/endpoints/api/emojis.go @@ -1,6 +1,7 @@ package api import ( + "context" "github.com/TicketsBot/GoPanel/botcontext" "github.com/TicketsBot/GoPanel/utils" "github.com/gin-gonic/gin" @@ -15,7 +16,8 @@ func EmojisHandler(ctx *gin.Context) { return } - emojis, err := botContext.GetGuildEmojis(guildId) + // TODO: Use proper context + emojis, err := botContext.GetGuildEmojis(context.Background(), guildId) if err != nil { ctx.JSON(500, utils.ErrorJson(err)) return diff --git a/app/http/endpoints/api/getpermissionlevel.go b/app/http/endpoints/api/getpermissionlevel.go index 65ad26f..6090df2 100644 --- a/app/http/endpoints/api/getpermissionlevel.go +++ b/app/http/endpoints/api/getpermissionlevel.go @@ -1,6 +1,7 @@ package api import ( + "context" "github.com/TicketsBot/GoPanel/utils" "github.com/gin-gonic/gin" "strconv" @@ -15,7 +16,8 @@ func GetPermissionLevel(ctx *gin.Context) { return } - permissionLevel, err := utils.GetPermissionLevel(guildId, userId) + // TODO: Use proper context + permissionLevel, err := utils.GetPermissionLevel(context.Background(), guildId, userId) if err != nil { ctx.JSON(500, utils.ErrorJson(err)) return diff --git a/app/http/endpoints/api/guilds.go b/app/http/endpoints/api/guilds.go index 62828eb..d32e11d 100644 --- a/app/http/endpoints/api/guilds.go +++ b/app/http/endpoints/api/guilds.go @@ -2,6 +2,7 @@ package api import ( "context" + "errors" dbclient "github.com/TicketsBot/GoPanel/database" "github.com/TicketsBot/GoPanel/rpc/cache" "github.com/TicketsBot/GoPanel/utils" @@ -63,10 +64,11 @@ func GetGuilds(ctx *gin.Context) { if g.Owner { permLevel = permission.Admin } else { - permLevel, err = utils.GetPermissionLevel(g.GuildId, userId) + permLevel, err = utils.GetPermissionLevel(context.Background(), g.GuildId, userId) if err != nil { // If a Discord error occurs, just skip the server - if _, ok := err.(request.RestError); !ok { + var restError request.RestError + if !errors.As(err, &restError) { return err } } diff --git a/app/http/endpoints/api/integrations/listintegrations.go b/app/http/endpoints/api/integrations/listintegrations.go index 28b329d..3dc2b77 100644 --- a/app/http/endpoints/api/integrations/listintegrations.go +++ b/app/http/endpoints/api/integrations/listintegrations.go @@ -1,6 +1,7 @@ package api import ( + "context" dbclient "github.com/TicketsBot/GoPanel/database" "github.com/TicketsBot/GoPanel/rpc/cache" "github.com/TicketsBot/GoPanel/utils" @@ -86,7 +87,8 @@ func ListIntegrationsHandler(ctx *gin.Context) { } // Get author data for the integrations - authors, err := cache.Instance.GetUsers(authorIds) + // TODO: Use proper context + authors, err := cache.Instance.GetUsers(context.Background(), authorIds) if err != nil { ctx.JSON(500, utils.ErrorJson(err)) return diff --git a/app/http/endpoints/api/integrations/setpublic.go b/app/http/endpoints/api/integrations/setpublic.go index c5fc1c0..1b5719a 100644 --- a/app/http/endpoints/api/integrations/setpublic.go +++ b/app/http/endpoints/api/integrations/setpublic.go @@ -1,6 +1,7 @@ package api import ( + "context" "fmt" "github.com/TicketsBot/GoPanel/botcontext" "github.com/TicketsBot/GoPanel/config" @@ -52,7 +53,10 @@ func SetIntegrationPublicHandler(ctx *gin.Context) { AddField("Integration Description", integration.Description, false) botCtx := botcontext.PublicContext() + + // TODO: Use proper context _, err = rest.ExecuteWebhook( + context.Background(), config.Conf.Bot.PublicIntegrationRequestWebhookToken, botCtx.RateLimiter, config.Conf.Bot.PublicIntegrationRequestWebhookId, diff --git a/app/http/endpoints/api/panel/multipanelcreate.go b/app/http/endpoints/api/panel/multipanelcreate.go index 4605055..755ae4c 100644 --- a/app/http/endpoints/api/panel/multipanelcreate.go +++ b/app/http/endpoints/api/panel/multipanelcreate.go @@ -74,7 +74,7 @@ func MultiPanelCreate(ctx *gin.Context) { } messageData := data.IntoMessageData(premiumTier > premium.None) - messageId, err := messageData.send(&botContext, panels) + messageId, err := messageData.send(botContext, panels) if err != nil { var unwrapped request.RestError if errors.As(err, &unwrapped); unwrapped.StatusCode == 403 { @@ -158,8 +158,12 @@ func (d *multiPanelCreateData) validateContent() (err error) { } func (d *multiPanelCreateData) validateChannel(guildId uint64) func() error { - return func() (err error) { - channels := cache.Instance.GetGuildChannels(guildId) + return func() error { + // TODO: Use proper context + channels, err := cache.Instance.GetGuildChannels(context.Background(), guildId) + if err != nil { + return err + } var valid bool for _, ch := range channels { @@ -170,10 +174,10 @@ func (d *multiPanelCreateData) validateChannel(guildId uint64) func() error { } if !valid { - err = errors.New("channel does not exist") + return errors.New("channel does not exist") } - return + return nil } } diff --git a/app/http/endpoints/api/panel/multipaneldelete.go b/app/http/endpoints/api/panel/multipaneldelete.go index aaefad1..8af437c 100644 --- a/app/http/endpoints/api/panel/multipaneldelete.go +++ b/app/http/endpoints/api/panel/multipaneldelete.go @@ -1,6 +1,7 @@ package api import ( + "context" "errors" "github.com/TicketsBot/GoPanel/botcontext" dbclient "github.com/TicketsBot/GoPanel/database" @@ -39,7 +40,8 @@ func MultiPanelDelete(ctx *gin.Context) { } var unwrapped request.RestError - if err := rest.DeleteMessage(botContext.Token, botContext.RateLimiter, panel.ChannelId, panel.MessageId); err != nil && !(errors.As(err, &unwrapped) && unwrapped.IsClientError()) { + // TODO: Use proper context + if err := rest.DeleteMessage(context.Background(), botContext.Token, botContext.RateLimiter, panel.ChannelId, panel.MessageId); err != nil && !(errors.As(err, &unwrapped) && unwrapped.IsClientError()) { ctx.JSON(500, utils.ErrorJson(err)) return } diff --git a/app/http/endpoints/api/panel/multipanelmessagedata.go b/app/http/endpoints/api/panel/multipanelmessagedata.go index 4cf8b1e..ee34b6a 100644 --- a/app/http/endpoints/api/panel/multipanelmessagedata.go +++ b/app/http/endpoints/api/panel/multipanelmessagedata.go @@ -1,6 +1,7 @@ package api import ( + "context" "github.com/TicketsBot/GoPanel/botcontext" "github.com/TicketsBot/GoPanel/utils/types" "github.com/TicketsBot/database" @@ -119,7 +120,8 @@ func (d *multiPanelMessageData) send(ctx *botcontext.BotContext, panels []databa Components: components, } - msg, err := rest.CreateMessage(ctx.Token, ctx.RateLimiter, d.ChannelId, data) + // TODO: Use proper context + msg, err := rest.CreateMessage(context.Background(), ctx.Token, ctx.RateLimiter, d.ChannelId, data) if err != nil { return 0, err } diff --git a/app/http/endpoints/api/panel/multipanelresend.go b/app/http/endpoints/api/panel/multipanelresend.go index cd362d8..7ef40bd 100644 --- a/app/http/endpoints/api/panel/multipanelresend.go +++ b/app/http/endpoints/api/panel/multipanelresend.go @@ -1,6 +1,7 @@ package api import ( + "context" "errors" "github.com/TicketsBot/GoPanel/botcontext" dbclient "github.com/TicketsBot/GoPanel/database" @@ -50,7 +51,8 @@ func MultiPanelResend(ctx *gin.Context) { } // delete old message - if err := rest.DeleteMessage(botContext.Token, botContext.RateLimiter, multiPanel.ChannelId, multiPanel.MessageId); err != nil { + // TODO: Use proper context + if err := rest.DeleteMessage(context.Background(), botContext.Token, botContext.RateLimiter, multiPanel.ChannelId, multiPanel.MessageId); err != nil { var unwrapped request.RestError if errors.As(err, &unwrapped) && !unwrapped.IsClientError() { ctx.JSON(500, utils.ErrorJson(err)) @@ -73,7 +75,7 @@ func MultiPanelResend(ctx *gin.Context) { // send new message messageData := multiPanelIntoMessageData(multiPanel, premiumTier > premium.None) - messageId, err := messageData.send(&botContext, panels) + messageId, err := messageData.send(botContext, panels) if err != nil { var unwrapped request.RestError if errors.As(err, &unwrapped) && unwrapped.StatusCode == 403 { diff --git a/app/http/endpoints/api/panel/multipanelupdate.go b/app/http/endpoints/api/panel/multipanelupdate.go index 76208e3..95f482b 100644 --- a/app/http/endpoints/api/panel/multipanelupdate.go +++ b/app/http/endpoints/api/panel/multipanelupdate.go @@ -3,6 +3,7 @@ package api import ( "context" "errors" + "github.com/TicketsBot/GoPanel/app" "github.com/TicketsBot/GoPanel/botcontext" dbclient "github.com/TicketsBot/GoPanel/database" "github.com/TicketsBot/GoPanel/rpc" @@ -16,46 +17,46 @@ import ( "strconv" ) -func MultiPanelUpdate(ctx *gin.Context) { - guildId := ctx.Keys["guildid"].(uint64) +func MultiPanelUpdate(c *gin.Context) { + guildId := c.Keys["guildid"].(uint64) // parse body var data multiPanelCreateData - if err := ctx.ShouldBindJSON(&data); err != nil { - ctx.JSON(400, utils.ErrorJson(err)) + if err := c.ShouldBindJSON(&data); err != nil { + c.JSON(400, utils.ErrorJson(err)) return } // parse panel ID - panelId, err := strconv.Atoi(ctx.Param("panelid")) + panelId, err := strconv.Atoi(c.Param("panelid")) if err != nil { - ctx.JSON(400, utils.ErrorJson(err)) + c.JSON(400, utils.ErrorJson(err)) return } // retrieve panel from DB multiPanel, ok, err := dbclient.Client.MultiPanels.Get(panelId) if err != nil { - ctx.JSON(500, utils.ErrorJson(err)) + c.JSON(500, utils.ErrorJson(err)) return } // check panel exists if !ok { - ctx.JSON(404, utils.ErrorJson(errors.New("No panel with the provided ID found"))) + c.JSON(404, utils.ErrorJson(errors.New("No panel with the provided ID found"))) return } // check panel is in the same guild if guildId != multiPanel.GuildId { - ctx.JSON(403, utils.ErrorJson(errors.New("Guild ID doesn't match"))) + c.JSON(403, utils.ErrorJson(errors.New("Guild ID doesn't match"))) return } // validate body & get sub-panels panels, err := data.doValidations(guildId) if err != nil { - ctx.JSON(400, utils.ErrorJson(err)) + c.JSON(400, utils.ErrorJson(err)) return } @@ -63,12 +64,12 @@ func MultiPanelUpdate(ctx *gin.Context) { if panel.CustomId == "" { panel.CustomId, err = utils.RandString(30) if err != nil { - ctx.JSON(500, utils.ErrorJson(err)) + c.JSON(500, utils.ErrorJson(err)) return } if err := dbclient.Client.Panel.Update(panel); err != nil { - ctx.JSON(500, utils.ErrorJson(err)) + c.JSON(500, utils.ErrorJson(err)) return } } @@ -77,33 +78,37 @@ func MultiPanelUpdate(ctx *gin.Context) { // get bot context botContext, err := botcontext.ContextForGuild(guildId) if err != nil { - ctx.JSON(500, utils.ErrorJson(err)) + c.JSON(500, utils.ErrorJson(err)) return } // delete old message + ctx, cancel := app.DefaultContext() + defer cancel() + var unwrapped request.RestError - if err := rest.DeleteMessage(botContext.Token, botContext.RateLimiter, multiPanel.ChannelId, multiPanel.MessageId); err != nil && !(errors.As(err, &unwrapped) && unwrapped.IsClientError()) { - ctx.JSON(500, utils.ErrorJson(err)) + if err := rest.DeleteMessage(ctx, botContext.Token, botContext.RateLimiter, multiPanel.ChannelId, multiPanel.MessageId); err != nil && !(errors.As(err, &unwrapped) && unwrapped.IsClientError()) { + c.JSON(500, utils.ErrorJson(err)) return } + cancel() // get premium status premiumTier, err := rpc.PremiumClient.GetTierByGuildId(guildId, true, botContext.Token, botContext.RateLimiter) if err != nil { - ctx.JSON(500, utils.ErrorJson(err)) + c.JSON(500, utils.ErrorJson(err)) return } // send new message messageData := data.IntoMessageData(premiumTier > premium.None) - messageId, err := messageData.send(&botContext, panels) + messageId, err := messageData.send(botContext, panels) if err != nil { var unwrapped request.RestError if errors.As(err, &unwrapped) && unwrapped.StatusCode == 403 { - ctx.JSON(500, utils.ErrorJson(errors.New("I do not have permission to send messages in the provided channel"))) + c.JSON(500, utils.ErrorJson(errors.New("I do not have permission to send messages in the provided channel"))) } else { - ctx.JSON(500, utils.ErrorJson(err)) + c.JSON(500, utils.ErrorJson(err)) } return @@ -124,14 +129,14 @@ func MultiPanelUpdate(ctx *gin.Context) { } if err = dbclient.Client.MultiPanels.Update(multiPanel.Id, updated); err != nil { - ctx.JSON(500, utils.ErrorJson(err)) + c.JSON(500, utils.ErrorJson(err)) return } // TODO: one query for ACID purposes // delete old targets if err := dbclient.Client.MultiPanelTargets.DeleteAll(multiPanel.Id); err != nil { - ctx.JSON(500, utils.ErrorJson(err)) + c.JSON(500, utils.ErrorJson(err)) return } @@ -146,11 +151,11 @@ func MultiPanelUpdate(ctx *gin.Context) { } if err := group.Wait(); err != nil { - ctx.JSON(500, utils.ErrorJson(err)) + c.JSON(500, utils.ErrorJson(err)) return } - ctx.JSON(200, gin.H{ + c.JSON(200, gin.H{ "success": true, "data": multiPanel, }) diff --git a/app/http/endpoints/api/panel/panelcreate.go b/app/http/endpoints/api/panel/panelcreate.go index aee45c1..554efa8 100644 --- a/app/http/endpoints/api/panel/panelcreate.go +++ b/app/http/endpoints/api/panel/panelcreate.go @@ -3,6 +3,7 @@ package api import ( "context" "errors" + "github.com/TicketsBot/GoPanel/app" "github.com/TicketsBot/GoPanel/app/http/validation" "github.com/TicketsBot/GoPanel/botcontext" dbclient "github.com/TicketsBot/GoPanel/database" @@ -64,19 +65,19 @@ func (p *panelBody) IntoPanelMessageData(customId string, isPremium bool) panelM var validate = validator.New() -func CreatePanel(ctx *gin.Context) { - guildId := ctx.Keys["guildid"].(uint64) +func CreatePanel(c *gin.Context) { + guildId := c.Keys["guildid"].(uint64) botContext, err := botcontext.ContextForGuild(guildId) if err != nil { - ctx.JSON(500, utils.ErrorJson(err)) + c.JSON(500, utils.ErrorJson(err)) return } var data panelBody - if err := ctx.BindJSON(&data); err != nil { - ctx.JSON(400, utils.ErrorJson(err)) + if err := c.BindJSON(&data); err != nil { + c.JSON(400, utils.ErrorJson(err)) return } @@ -85,19 +86,19 @@ func CreatePanel(ctx *gin.Context) { // Check panel quota premiumTier, err := rpc.PremiumClient.GetTierByGuildId(guildId, false, botContext.Token, botContext.RateLimiter) if err != nil { - ctx.JSON(500, utils.ErrorJson(err)) + c.JSON(500, utils.ErrorJson(err)) return } if premiumTier == premium.None { panels, err := dbclient.Client.Panel.GetByGuild(guildId) if err != nil { - ctx.JSON(500, utils.ErrorJson(err)) + c.JSON(500, utils.ErrorJson(err)) return } if len(panels) >= freePanelLimit { - ctx.JSON(402, utils.ErrorStr("You have exceeded your panel quota. Purchase premium to unlock more panels.")) + c.JSON(402, utils.ErrorStr("You have exceeded your panel quota. Purchase premium to unlock more panels.")) return } } @@ -105,15 +106,18 @@ func CreatePanel(ctx *gin.Context) { // Apply defaults ApplyPanelDefaults(&data) - channels, err := botContext.GetGuildChannels(guildId) + ctx, cancel := app.DefaultContext() + defer cancel() + + channels, err := botContext.GetGuildChannels(ctx, guildId) if err != nil { - ctx.JSON(500, utils.ErrorJson(err)) + c.JSON(500, utils.ErrorJson(err)) return } - roles, err := botContext.GetGuildRoles(guildId) + roles, err := botContext.GetGuildRoles(ctx, guildId) if err != nil { - ctx.JSON(500, utils.ErrorJson(err)) + c.JSON(500, utils.ErrorJson(err)) return } @@ -130,9 +134,9 @@ func CreatePanel(ctx *gin.Context) { if err := ValidatePanelBody(validationContext); err != nil { var validationError *validation.InvalidInputError if errors.As(err, &validationError) { - ctx.JSON(400, utils.ErrorStr(validationError.Error())) + c.JSON(400, utils.ErrorStr(validationError.Error())) } else { - ctx.JSON(500, utils.ErrorJson(err)) + c.JSON(500, utils.ErrorJson(err)) } return @@ -140,32 +144,32 @@ func CreatePanel(ctx *gin.Context) { // Do tag validation if err := validate.Struct(data); err != nil { - validationErrors, ok := err.(validator.ValidationErrors) - if !ok { - ctx.JSON(500, utils.ErrorStr("An error occurred while validating the panel")) + var validationErrors validator.ValidationErrors + if ok := errors.As(err, &validationErrors); !ok { + c.JSON(500, utils.ErrorStr("An error occurred while validating the panel")) return } formatted := "Your input contained the following errors:\n" + utils.FormatValidationErrors(validationErrors) - ctx.JSON(400, utils.ErrorStr(formatted)) + c.JSON(400, utils.ErrorStr(formatted)) return } customId, err := utils.RandString(30) if err != nil { - ctx.JSON(500, utils.ErrorJson(err)) + c.JSON(500, utils.ErrorJson(err)) return } messageData := data.IntoPanelMessageData(customId, premiumTier > premium.None) - msgId, err := messageData.send(&botContext) + msgId, err := messageData.send(botContext) if err != nil { var unwrapped request.RestError if errors.As(err, &unwrapped) && unwrapped.StatusCode == 403 { - ctx.JSON(500, utils.ErrorStr("I do not have permission to send messages in the specified channel")) + c.JSON(500, utils.ErrorStr("I do not have permission to send messages in the specified channel")) } else { // TODO: Most appropriate error? - ctx.JSON(500, utils.ErrorJson(err)) + c.JSON(500, utils.ErrorJson(err)) } return @@ -192,7 +196,7 @@ func CreatePanel(ctx *gin.Context) { id, err := dbclient.Client.Embeds.CreateWithFields(embed, fields) if err != nil { - ctx.JSON(500, utils.ErrorJson(err)) + c.JSON(500, utils.ErrorJson(err)) return } @@ -240,7 +244,7 @@ func CreatePanel(ctx *gin.Context) { } else { roleId, err := strconv.ParseUint(mention, 10, 64) if err != nil { - ctx.JSON(400, utils.ErrorStr("Invalid role ID")) + c.JSON(400, utils.ErrorStr("Invalid role ID")) return } @@ -250,13 +254,13 @@ func CreatePanel(ctx *gin.Context) { } } - panelId, err := storePanel(ctx, panel, createOptions) + panelId, err := storePanel(c, panel, createOptions) if err != nil { - ctx.JSON(500, utils.ErrorJson(err)) + c.JSON(500, utils.ErrorJson(err)) return } - ctx.JSON(200, gin.H{ + c.JSON(200, gin.H{ "success": true, "panel_id": panelId, }) diff --git a/app/http/endpoints/api/panel/paneldelete.go b/app/http/endpoints/api/panel/paneldelete.go index dd3d8f3..95c4f42 100644 --- a/app/http/endpoints/api/panel/paneldelete.go +++ b/app/http/endpoints/api/panel/paneldelete.go @@ -1,6 +1,7 @@ package api import ( + "context" "errors" "github.com/TicketsBot/GoPanel/botcontext" "github.com/TicketsBot/GoPanel/database" @@ -65,7 +66,8 @@ func DeletePanel(ctx *gin.Context) { return } - if err := rest.DeleteMessage(botContext.Token, botContext.RateLimiter, panel.ChannelId, panel.MessageId); err != nil { + // TODO: Use proper context + if err := rest.DeleteMessage(context.Background(), botContext.Token, botContext.RateLimiter, panel.ChannelId, panel.MessageId); err != nil { var unwrapped request.RestError if !errors.As(err, &unwrapped) || unwrapped.StatusCode != 404 { ctx.JSON(500, utils.ErrorJson(err)) @@ -102,7 +104,7 @@ func DeletePanel(ctx *gin.Context) { IsPremium: premiumTier > premium.None, } - messageId, err := messageData.send(&botContext, panels) + messageId, err := messageData.send(botContext, panels) if err != nil { ctx.JSON(500, utils.ErrorJson(err)) return @@ -114,7 +116,8 @@ func DeletePanel(ctx *gin.Context) { } // Delete old panel - _ = rest.DeleteMessage(botContext.Token, botContext.RateLimiter, multiPanel.ChannelId, multiPanel.MessageId) + // TODO: Use proper context + _ = rest.DeleteMessage(context.Background(), botContext.Token, botContext.RateLimiter, multiPanel.ChannelId, multiPanel.MessageId) } ctx.JSON(200, utils.SuccessResponse) diff --git a/app/http/endpoints/api/panel/panelmessagedata.go b/app/http/endpoints/api/panel/panelmessagedata.go index 8fed239..d94563e 100644 --- a/app/http/endpoints/api/panel/panelmessagedata.go +++ b/app/http/endpoints/api/panel/panelmessagedata.go @@ -1,6 +1,7 @@ package api import ( + "github.com/TicketsBot/GoPanel/app" "github.com/TicketsBot/GoPanel/botcontext" "github.com/TicketsBot/database" "github.com/rxdn/gdl/objects" @@ -54,7 +55,7 @@ func panelIntoMessageData(panel database.Panel, isPremium bool) panelMessageData } } -func (p *panelMessageData) send(ctx *botcontext.BotContext) (uint64, error) { +func (p *panelMessageData) send(c *botcontext.BotContext) (uint64, error) { e := embed.NewEmbed(). SetTitle(p.Title). SetDescription(p.Content). @@ -86,7 +87,10 @@ func (p *panelMessageData) send(ctx *botcontext.BotContext) (uint64, error) { }, } - msg, err := rest.CreateMessage(ctx.Token, ctx.RateLimiter, p.ChannelId, data) + ctx, cancel := app.DefaultContext() + defer cancel() + + msg, err := rest.CreateMessage(ctx, c.Token, c.RateLimiter, p.ChannelId, data) if err != nil { return 0, err } diff --git a/app/http/endpoints/api/panel/panelresend.go b/app/http/endpoints/api/panel/panelresend.go index 2fa692e..2b75680 100644 --- a/app/http/endpoints/api/panel/panelresend.go +++ b/app/http/endpoints/api/panel/panelresend.go @@ -1,6 +1,7 @@ package api import ( + "context" "errors" "github.com/TicketsBot/GoPanel/botcontext" dbclient "github.com/TicketsBot/GoPanel/database" @@ -52,7 +53,8 @@ func ResendPanel(ctx *gin.Context) { } // delete old message - if err := rest.DeleteMessage(botContext.Token, botContext.RateLimiter, panel.ChannelId, panel.GuildId); err != nil { + // TODO: Use proper context + if err := rest.DeleteMessage(context.Background(), botContext.Token, botContext.RateLimiter, panel.ChannelId, panel.GuildId); err != nil { var unwrapped request.RestError if errors.As(err, &unwrapped) && !unwrapped.IsClientError() { ctx.JSON(500, utils.ErrorJson(err)) @@ -67,7 +69,7 @@ func ResendPanel(ctx *gin.Context) { } messageData := panelIntoMessageData(panel, premiumTier > premium.None) - msgId, err := messageData.send(&botContext) + msgId, err := messageData.send(botContext) if err != nil { var unwrapped request.RestError if errors.As(err, &unwrapped) && unwrapped.StatusCode == 403 { diff --git a/app/http/endpoints/api/panel/panelupdate.go b/app/http/endpoints/api/panel/panelupdate.go index 8214ec9..f1ec1e4 100644 --- a/app/http/endpoints/api/panel/panelupdate.go +++ b/app/http/endpoints/api/panel/panelupdate.go @@ -1,6 +1,7 @@ package api import ( + "context" "errors" "github.com/TicketsBot/GoPanel/app/http/validation" "github.com/TicketsBot/GoPanel/botcontext" @@ -66,13 +67,15 @@ func UpdatePanel(ctx *gin.Context) { return } - channels, err := botContext.GetGuildChannels(guildId) + // TODO: Use proper context + channels, err := botContext.GetGuildChannels(context.Background(), guildId) if err != nil { ctx.JSON(500, utils.ErrorJson(err)) return } - roles, err := botContext.GetGuildRoles(guildId) + // TODO: Use proper context + roles, err := botContext.GetGuildRoles(context.Background(), guildId) if err != nil { ctx.JSON(500, utils.ErrorJson(err)) return @@ -142,10 +145,11 @@ func UpdatePanel(ctx *gin.Context) { if shouldUpdateMessage { // delete old message, ignoring error - _ = rest.DeleteMessage(botContext.Token, botContext.RateLimiter, existing.ChannelId, existing.MessageId) + // TODO: Use proper context + _ = rest.DeleteMessage(context.Background(), botContext.Token, botContext.RateLimiter, existing.ChannelId, existing.MessageId) messageData := data.IntoPanelMessageData(existing.CustomId, premiumTier > premium.None) - newMessageId, err = messageData.send(&botContext) + newMessageId, err = messageData.send(botContext) if err != nil { var unwrapped request.RestError if errors.As(err, &unwrapped) { @@ -313,7 +317,7 @@ func UpdatePanel(ctx *gin.Context) { ThumbnailUrl: multiPanel.ThumbnailUrl, } - messageId, err := messageData.send(&botContext, panels) + messageId, err := messageData.send(botContext, panels) if err != nil { ctx.JSON(500, utils.ErrorJson(err)) return @@ -325,7 +329,8 @@ func UpdatePanel(ctx *gin.Context) { } // Delete old panel - _ = rest.DeleteMessage(botContext.Token, botContext.RateLimiter, multiPanel.ChannelId, multiPanel.MessageId) + // TODO: Use proper context + _ = rest.DeleteMessage(context.Background(), botContext.Token, botContext.RateLimiter, multiPanel.ChannelId, multiPanel.MessageId) } ctx.JSON(200, utils.SuccessResponse) diff --git a/app/http/endpoints/api/panel/validation.go b/app/http/endpoints/api/panel/validation.go index 05db7cc..d859f75 100644 --- a/app/http/endpoints/api/panel/validation.go +++ b/app/http/endpoints/api/panel/validation.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "github.com/TicketsBot/GoPanel/app" "github.com/TicketsBot/GoPanel/app/http/validation" "github.com/TicketsBot/GoPanel/app/http/validation/defaults" "github.com/TicketsBot/GoPanel/botcontext" @@ -42,7 +43,7 @@ type PanelValidationContext struct { Data panelBody GuildId uint64 IsPremium bool - BotContext botcontext.BotContext + BotContext *botcontext.BotContext Channels []channel.Channel Roles []guild.Role } @@ -118,16 +119,19 @@ func validateCategory(ctx PanelValidationContext) validation.ValidationFunc { } } -func validateEmoji(ctx PanelValidationContext) validation.ValidationFunc { +func validateEmoji(c PanelValidationContext) validation.ValidationFunc { return func() error { - emoji := ctx.Data.Emoji + emoji := c.Data.Emoji if emoji.IsCustomEmoji { if emoji.Id == nil { return validation.NewInvalidInputError("Custom emoji was missing ID") } - resolvedEmoji, err := ctx.BotContext.GetGuildEmoji(ctx.GuildId, *emoji.Id) + ctx, cancel := context.WithTimeout(context.Background(), app.DefaultTimeout) + defer cancel() + + resolvedEmoji, err := c.BotContext.GetGuildEmoji(ctx, c.GuildId, *emoji.Id) if err != nil { return err } diff --git a/app/http/endpoints/api/searchmembers.go b/app/http/endpoints/api/searchmembers.go index f687e28..a8ddaac 100644 --- a/app/http/endpoints/api/searchmembers.go +++ b/app/http/endpoints/api/searchmembers.go @@ -1,6 +1,7 @@ package api import ( + "context" "github.com/TicketsBot/GoPanel/botcontext" "github.com/TicketsBot/GoPanel/utils" "github.com/gin-gonic/gin" @@ -24,9 +25,11 @@ func SearchMembers(ctx *gin.Context) { var members []member.Member if query == "" { - members, err = botCtx.ListMembers(guildId) + // TODO: Use proper context + members, err = botCtx.ListMembers(context.Background(), guildId) } else { - members, err = botCtx.SearchMembers(guildId, query) + // TODO: Use proper context + members, err = botCtx.SearchMembers(context.Background(), guildId, query) } if err != nil { diff --git a/app/http/endpoints/api/settings/updatesettings.go b/app/http/endpoints/api/settings/updatesettings.go index 52fc1dd..04256b0 100644 --- a/app/http/endpoints/api/settings/updatesettings.go +++ b/app/http/endpoints/api/settings/updatesettings.go @@ -35,7 +35,8 @@ func UpdateSettingsHandler(ctx *gin.Context) { return } - channels, err := botContext.GetGuildChannels(guildId) + // TODO: Use proper context + channels, err := botContext.GetGuildChannels(context.Background(), guildId) if err != nil { ctx.JSON(500, utils.ErrorJson(err)) return @@ -210,8 +211,11 @@ func (s *Settings) Validate(guildId uint64, premiumTier premium.PremiumTier) err group.Go(func() error { if s.Settings.OverflowCategoryId != nil { - ch, ok := cache.Instance.GetChannel(*s.Settings.OverflowCategoryId) - if !ok { + ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) + defer cancel() + + ch, err := cache.Instance.GetChannel(ctx, *s.Settings.OverflowCategoryId) + if err != nil { return fmt.Errorf("Invalid overflow category") } @@ -229,8 +233,11 @@ func (s *Settings) Validate(guildId uint64, premiumTier premium.PremiumTier) err group.Go(func() error { if s.Settings.TicketNotificationChannel != nil { - ch, ok := cache.Instance.GetChannel(*s.Settings.TicketNotificationChannel) - if !ok { + ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) + defer cancel() + + ch, err := cache.Instance.GetChannel(ctx, *s.Settings.TicketNotificationChannel) + if err != nil { return fmt.Errorf("Invalid ticket notification channel") } diff --git a/app/http/endpoints/api/team/getmembers.go b/app/http/endpoints/api/team/getmembers.go index 7cbab7f..302a709 100644 --- a/app/http/endpoints/api/team/getmembers.go +++ b/app/http/endpoints/api/team/getmembers.go @@ -129,7 +129,8 @@ func formatMembers(guildId uint64, userIds, roleIds []uint64) ([]entity, error) group.Go(func() error { defer wg.Done() - user, err := ctx.GetUser(userId) + // TODO: Use proper context + user, err := ctx.GetUser(context.Background(), userId) if err != nil { // TODO: Log w sentry return nil // We should skip the error, since it's probably 403 / 404 etc diff --git a/app/http/endpoints/api/team/removemember.go b/app/http/endpoints/api/team/removemember.go index f55c41f..48c4fa6 100644 --- a/app/http/endpoints/api/team/removemember.go +++ b/app/http/endpoints/api/team/removemember.go @@ -1,6 +1,8 @@ package api import ( + "context" + "errors" "fmt" "github.com/TicketsBot/GoPanel/botcontext" dbclient "github.com/TicketsBot/GoPanel/database" @@ -72,7 +74,8 @@ func removeDefaultMember(ctx *gin.Context, guildId, selfId, snowflake uint64, en return } - guild, err := botCtx.GetGuild(guildId) + // TODO: Use proper context + guild, err := botCtx.GetGuild(context.Background(), guildId) if err != nil { ctx.JSON(500, utils.ErrorJson(err)) return @@ -112,11 +115,13 @@ func removeDefaultMember(ctx *gin.Context, guildId, selfId, snowflake uint64, en if entityType == entityTypeUser { // If the member is not in the guild we do not have to worry - member, err := botContext.GetGuildMember(guildId, snowflake) + // TODO: Use proper context + member, err := botContext.GetGuildMember(context.Background(), guildId, snowflake) if err == nil { if member.HasRole(*metadata.OnCallRole) { // Attempt to remove role but ignore failure - _ = botContext.RemoveGuildMemberRole(guildId, snowflake, *metadata.OnCallRole) + // TODO: Use proper context + _ = botContext.RemoveGuildMemberRole(context.Background(), guildId, snowflake, *metadata.OnCallRole) } } else { if err, ok := err.(request.RestError); !ok || err.StatusCode != 404 { @@ -131,7 +136,8 @@ func removeDefaultMember(ctx *gin.Context, guildId, selfId, snowflake uint64, en return } - if err := botContext.DeleteGuildRole(guildId, *metadata.OnCallRole); err != nil && !isUnknownRoleError(err) { + // TODO: Use proper context + if err := botContext.DeleteGuildRole(context.Background(), guildId, *metadata.OnCallRole); err != nil && !isUnknownRoleError(err) { ctx.JSON(500, utils.ErrorJson(err)) return } @@ -184,19 +190,24 @@ func removeTeamMember(ctx *gin.Context, teamId int, guildId, snowflake uint64, e if entityType == entityTypeUser { // If the member is not in the guild we do not have to worry - member, err := botContext.GetGuildMember(guildId, snowflake) + // TODO: Use proper context + member, err := botContext.GetGuildMember(context.Background(), guildId, snowflake) if err == nil { if member.HasRole(*team.OnCallRole) { // Attempt to remove role but ignore failure - _ = botContext.RemoveGuildMemberRole(guildId, snowflake, *team.OnCallRole) + // TODO: Use proper context + _ = botContext.RemoveGuildMemberRole(context.Background(), guildId, snowflake, *team.OnCallRole) } } else { - if err, ok := err.(request.RestError); !ok || err.StatusCode != 404 { + var err request.RestError + if !errors.As(err, &err) || err.StatusCode != 404 { ctx.JSON(500, utils.ErrorJson(err)) return } } - _ = botContext.RemoveGuildMemberRole(guildId, snowflake, *team.OnCallRole) + + // TODO: Use proper context + _ = botContext.RemoveGuildMemberRole(context.Background(), guildId, snowflake, *team.OnCallRole) } else if entityType == entityTypeRole { // Recreate role if err := dbclient.Client.SupportTeam.SetOnCallRole(teamId, nil); err != nil { @@ -204,7 +215,8 @@ func removeTeamMember(ctx *gin.Context, teamId int, guildId, snowflake uint64, e return } - if err := botContext.DeleteGuildRole(guildId, *team.OnCallRole); err != nil && !isUnknownRoleError(err) { + // TODO: Use proper context + if err := botContext.DeleteGuildRole(context.Background(), guildId, *team.OnCallRole); err != nil && !isUnknownRoleError(err) { ctx.JSON(500, utils.ErrorJson(err)) return } @@ -221,7 +233,7 @@ func removeTeamMember(ctx *gin.Context, teamId int, guildId, snowflake uint64, e ctx.JSON(200, utils.SuccessResponse) } -func createOnCallRole(botContext botcontext.BotContext, guildId uint64, team *database.SupportTeam) (uint64, error) { +func createOnCallRole(botContext *botcontext.BotContext, guildId uint64, team *database.SupportTeam) (uint64, error) { var roleName string if team == nil { roleName = "On Call" // TODO: Translate @@ -235,7 +247,8 @@ func createOnCallRole(botContext botcontext.BotContext, guildId uint64, team *da Mentionable: utils.Ptr(false), } - role, err := botContext.CreateGuildRole(guildId, data) + // TODO: Use proper context + role, err := botContext.CreateGuildRole(context.Background(), guildId, data) if err != nil { return 0, err } @@ -254,7 +267,8 @@ func createOnCallRole(botContext botcontext.BotContext, guildId uint64, team *da } func isUnknownRoleError(err error) bool { - if err, ok := err.(request.RestError); ok && err.ApiError.Message == "Unknown Role" { + var restErr request.RestError + if errors.As(err, &restErr) && restErr.ApiError.Message == "Unknown Role" { return true } diff --git a/app/http/endpoints/api/ticket/closeticket.go b/app/http/endpoints/api/ticket/closeticket.go index 02a3207..9183fa2 100644 --- a/app/http/endpoints/api/ticket/closeticket.go +++ b/app/http/endpoints/api/ticket/closeticket.go @@ -1,6 +1,7 @@ package api import ( + "context" "github.com/TicketsBot/GoPanel/database" "github.com/TicketsBot/GoPanel/redis" "github.com/TicketsBot/GoPanel/utils" @@ -54,7 +55,7 @@ func CloseTicket(ctx *gin.Context) { return } - hasPermission, requestErr := utils.HasPermissionToViewTicket(guildId, userId, ticket) + hasPermission, requestErr := utils.HasPermissionToViewTicket(context.Background(), guildId, userId, ticket) if requestErr != nil { ctx.JSON(requestErr.StatusCode, utils.ErrorJson(requestErr)) return diff --git a/app/http/endpoints/api/ticket/getticket.go b/app/http/endpoints/api/ticket/getticket.go index b0b67e7..d7d2eac 100644 --- a/app/http/endpoints/api/ticket/getticket.go +++ b/app/http/endpoints/api/ticket/getticket.go @@ -1,12 +1,15 @@ package api import ( + "context" + "errors" "fmt" "github.com/TicketsBot/GoPanel/botcontext" "github.com/TicketsBot/GoPanel/database" "github.com/TicketsBot/GoPanel/rpc/cache" "github.com/TicketsBot/GoPanel/utils" "github.com/gin-gonic/gin" + cache2 "github.com/rxdn/gdl/cache" "github.com/rxdn/gdl/rest" "regexp" "strconv" @@ -63,7 +66,7 @@ func GetTicket(ctx *gin.Context) { return } - hasPermission, requestErr := utils.HasPermissionToViewTicket(guildId, userId, ticket) + hasPermission, requestErr := utils.HasPermissionToViewTicket(context.Background(), guildId, userId, ticket) if requestErr != nil { ctx.JSON(requestErr.StatusCode, utils.ErrorJson(requestErr)) return @@ -77,7 +80,11 @@ func GetTicket(ctx *gin.Context) { messagesFormatted := make([]map[string]interface{}, 0) if ticket.ChannelId != nil { // Get messages - messages, _ := rest.GetChannelMessages(botContext.Token, botContext.RateLimiter, *ticket.ChannelId, rest.GetChannelMessagesData{Limit: 100}) + messages, err := rest.GetChannelMessages(context.Background(), botContext.Token, botContext.RateLimiter, *ticket.ChannelId, rest.GetChannelMessagesData{Limit: 100}) + if err != nil { + ctx.JSON(500, utils.ErrorJson(err)) + return + } // Format messages, exclude unneeded data for _, message := range utils.Reverse(messages) { @@ -92,8 +99,15 @@ func GetTicket(ctx *gin.Context) { continue } - user, _ := cache.Instance.GetUser(mentionedId) - content = strings.ReplaceAll(content, fmt.Sprintf("<@%d>", mentionedId), fmt.Sprintf("@%s", user.Username)) + user, err := cache.Instance.GetUser(context.Background(), mentionedId) + if err == nil { + content = strings.ReplaceAll(content, fmt.Sprintf("<@%d>", mentionedId), fmt.Sprintf("@%s", user.Username)) + } else if errors.Is(err, cache2.ErrNotFound) { + content = strings.ReplaceAll(content, fmt.Sprintf("<@%d>", mentionedId), "@Unknown User") + } else { + ctx.JSON(500, utils.ErrorJson(err)) + return + } } } diff --git a/app/http/endpoints/api/ticket/gettickets.go b/app/http/endpoints/api/ticket/gettickets.go index ea0562b..af069b1 100644 --- a/app/http/endpoints/api/ticket/gettickets.go +++ b/app/http/endpoints/api/ticket/gettickets.go @@ -1,6 +1,7 @@ package api import ( + "context" "github.com/TicketsBot/GoPanel/database" "github.com/TicketsBot/GoPanel/rpc/cache" "github.com/TicketsBot/GoPanel/utils" @@ -40,7 +41,7 @@ func GetTickets(ctx *gin.Context) { userIds[i] = ticket.UserId } - users, err := cache.Instance.GetUsers(userIds) + users, err := cache.Instance.GetUsers(context.Background(), userIds) if err != nil { ctx.JSON(500, utils.ErrorJson(err)) return diff --git a/app/http/endpoints/api/ticket/livechat/eventhandler.go b/app/http/endpoints/api/ticket/livechat/eventhandler.go index cd49d02..0afd048 100644 --- a/app/http/endpoints/api/ticket/livechat/eventhandler.go +++ b/app/http/endpoints/api/ticket/livechat/eventhandler.go @@ -1,6 +1,7 @@ package livechat import ( + "context" "encoding/json" "errors" "fmt" @@ -77,7 +78,7 @@ func (c *Client) handleAuthEvent(data AuthData) error { } // Verify the user has permissions to be here - hasPermission, requestErr := utils.HasPermissionToViewTicket(c.GuildId, userId, ticket) + hasPermission, requestErr := utils.HasPermissionToViewTicket(context.Background(), c.GuildId, userId, ticket) if requestErr != nil { return api.NewErrorWithMessage(http.StatusInternalServerError, err, "Error retrieving permission data") } diff --git a/app/http/endpoints/api/ticket/sendmessage.go b/app/http/endpoints/api/ticket/sendmessage.go index a28471c..df1ed1a 100644 --- a/app/http/endpoints/api/ticket/sendmessage.go +++ b/app/http/endpoints/api/ticket/sendmessage.go @@ -1,12 +1,12 @@ package api import ( + "context" "errors" "fmt" "github.com/TicketsBot/GoPanel/botcontext" "github.com/TicketsBot/GoPanel/database" "github.com/TicketsBot/GoPanel/rpc" - "github.com/TicketsBot/GoPanel/rpc/cache" "github.com/TicketsBot/GoPanel/utils" "github.com/TicketsBot/common/premium" "github.com/gin-gonic/gin" @@ -95,8 +95,6 @@ func SendMessage(ctx *gin.Context) { return } - user, _ := cache.Instance.GetUser(userId) - if len(body.Message) > 2000 { body.Message = body.Message[0:1999] } @@ -111,13 +109,42 @@ func SendMessage(ctx *gin.Context) { return } + settings, err := database.Client.Settings.Get(guildId) + if err != nil { + ctx.JSON(500, utils.ErrorStr("Failed to fetch settings")) + return + } + if webhook.Id != 0 { + var webhookData rest.WebhookBody + if settings.AnonymiseDashboardResponses { + guild, err := botContext.GetGuild(context.Background(), guildId) + if err != nil { + ctx.JSON(500, utils.ErrorStr("Failed to fetch guild")) + return + } + + webhookData = rest.WebhookBody{ + Content: body.Message, + Username: guild.Name, + AvatarUrl: guild.IconUrl(), + } + } else { + user, err := botContext.GetUser(context.Background(), userId) + if err != nil { + ctx.JSON(500, utils.ErrorStr("Failed to fetch user")) + return + } + + webhookData = rest.WebhookBody{ + Content: body.Message, + Username: user.EffectiveName(), + AvatarUrl: user.AvatarUrl(256), + } + } + // TODO: Ratelimit - _, err = rest.ExecuteWebhook(webhook.Token, nil, webhook.Id, true, rest.WebhookBody{ - Content: body.Message, - Username: user.Username, - AvatarUrl: user.AvatarUrl(256), - }) + _, err = rest.ExecuteWebhook(ctx, webhook.Token, nil, webhook.Id, true, webhookData) if err != nil { // We can delete the webhook in this case @@ -133,9 +160,19 @@ func SendMessage(ctx *gin.Context) { } } - body.Message = fmt.Sprintf("**%s**: %s", user.Username, body.Message) - if len(body.Message) > 2000 { - body.Message = body.Message[0:1999] + message := body.Message + if !settings.AnonymiseDashboardResponses { + user, err := botContext.GetUser(context.Background(), userId) + if err != nil { + ctx.JSON(500, utils.ErrorStr("Failed to fetch user")) + return + } + + message = fmt.Sprintf("**%s**: %s", user.EffectiveName(), message) + } + + if len(message) > 2000 { + message = message[0:1999] } if ticket.ChannelId == nil { @@ -146,7 +183,7 @@ func SendMessage(ctx *gin.Context) { return } - if _, err = rest.CreateMessage(botContext.Token, botContext.RateLimiter, *ticket.ChannelId, rest.CreateMessageData{Content: body.Message}); err != nil { + if _, err = rest.CreateMessage(ctx, botContext.Token, botContext.RateLimiter, *ticket.ChannelId, rest.CreateMessageData{Content: message}); err != nil { ctx.JSON(500, gin.H{ "success": false, "error": err.Error(), diff --git a/app/http/endpoints/api/transcripts/get.go b/app/http/endpoints/api/transcripts/get.go index aae3719..886a8fc 100644 --- a/app/http/endpoints/api/transcripts/get.go +++ b/app/http/endpoints/api/transcripts/get.go @@ -1,6 +1,7 @@ package api import ( + "context" "errors" dbclient "github.com/TicketsBot/GoPanel/database" "github.com/TicketsBot/GoPanel/utils" @@ -39,7 +40,7 @@ func GetTranscriptHandler(ctx *gin.Context) { // Verify the user has permissions to be here // ticket.UserId cannot be 0 if ticket.UserId != userId { - hasPermission, err := utils.HasPermissionToViewTicket(guildId, userId, ticket) + hasPermission, err := utils.HasPermissionToViewTicket(context.Background(), guildId, userId, ticket) if err != nil { ctx.JSON(err.StatusCode, utils.ErrorJson(err)) return diff --git a/app/http/endpoints/api/transcripts/list.go b/app/http/endpoints/api/transcripts/list.go index 48dffa2..a5900d6 100644 --- a/app/http/endpoints/api/transcripts/list.go +++ b/app/http/endpoints/api/transcripts/list.go @@ -1,11 +1,14 @@ package api import ( + "context" + "errors" "github.com/TicketsBot/GoPanel/botcontext" dbclient "github.com/TicketsBot/GoPanel/database" "github.com/TicketsBot/GoPanel/rpc/cache" "github.com/TicketsBot/GoPanel/utils" "github.com/gin-gonic/gin" + cache2 "github.com/rxdn/gdl/cache" ) const pageLimit = 15 @@ -57,16 +60,19 @@ func ListTranscripts(ctx *gin.Context) { } // check cache, for some reason botContext.GetUser doesn't do this - user, ok := cache.Instance.GetUser(ticket.UserId) - if ok { + user, err := cache.Instance.GetUser(context.Background(), ticket.UserId) + if err == nil { usernames[ticket.UserId] = user.Username - } else { - user, err = botContext.GetUser(ticket.UserId) + } else if errors.Is(err, cache2.ErrNotFound) { + user, err = botContext.GetUser(context.Background(), ticket.UserId) if err != nil { // TODO: Log usernames[ticket.UserId] = "Unknown User" } else { usernames[ticket.UserId] = user.Username } + } else { + ctx.JSON(500, utils.ErrorJson(err)) + return } } diff --git a/app/http/endpoints/api/transcripts/listself.go b/app/http/endpoints/api/transcripts/listself.go index 29a526c..bf3b2d6 100644 --- a/app/http/endpoints/api/transcripts/listself.go +++ b/app/http/endpoints/api/transcripts/listself.go @@ -2,11 +2,13 @@ package api import ( "context" + "errors" dbclient "github.com/TicketsBot/GoPanel/database" "github.com/TicketsBot/GoPanel/rpc/cache" "github.com/TicketsBot/GoPanel/utils" "github.com/TicketsBot/database" "github.com/gin-gonic/gin" + cache2 "github.com/rxdn/gdl/cache" gdlutils "github.com/rxdn/gdl/utils" "golang.org/x/sync/errgroup" "strconv" @@ -55,11 +57,13 @@ func ListSelfTranscripts(ctx *gin.Context) { group.Go(func() error { var guildName string { - guild, ok := cache.Instance.GetGuild(ticket.GuildId) - if ok { + guild, err := cache.Instance.GetGuild(context.Background(), ticket.GuildId) + if err == nil { guildName = guild.Name - } else { + } else if errors.Is(err, cache2.ErrNotFound) { guildName = "Unknown server" + } else { + return err } } diff --git a/app/http/endpoints/api/transcripts/queryoptions.go b/app/http/endpoints/api/transcripts/queryoptions.go index 509d276..9c4c62e 100644 --- a/app/http/endpoints/api/transcripts/queryoptions.go +++ b/app/http/endpoints/api/transcripts/queryoptions.go @@ -1,6 +1,7 @@ package api import ( + "context" "errors" "github.com/TicketsBot/GoPanel/botcontext" "github.com/TicketsBot/database" @@ -68,7 +69,7 @@ func usernameToIds(guildId uint64, username string) ([]uint64, error) { return nil, err } - members, err := botContext.SearchMembers(guildId, username) + members, err := botContext.SearchMembers(context.Background(), guildId, username) if err != nil { return nil, err } diff --git a/app/http/endpoints/api/transcripts/render.go b/app/http/endpoints/api/transcripts/render.go index f750e2a..62d9062 100644 --- a/app/http/endpoints/api/transcripts/render.go +++ b/app/http/endpoints/api/transcripts/render.go @@ -40,7 +40,7 @@ func GetTranscriptRenderHandler(ctx *gin.Context) { // Verify the user has permissions to be here // ticket.UserId cannot be 0 if ticket.UserId != userId { - hasPermission, err := utils.HasPermissionToViewTicket(guildId, userId, ticket) + hasPermission, err := utils.HasPermissionToViewTicket(ctx, guildId, userId, ticket) if err != nil { ctx.JSON(err.StatusCode, utils.ErrorJson(err)) return diff --git a/app/http/endpoints/api/whitelabel/whitelabelcreateinteractions.go b/app/http/endpoints/api/whitelabel/whitelabelcreateinteractions.go index 8ca3c88..5fa943c 100644 --- a/app/http/endpoints/api/whitelabel/whitelabelcreateinteractions.go +++ b/app/http/endpoints/api/whitelabel/whitelabelcreateinteractions.go @@ -1,6 +1,7 @@ package api import ( + "context" "fmt" "github.com/TicketsBot/GoPanel/botcontext" "github.com/TicketsBot/GoPanel/database" @@ -67,7 +68,8 @@ func GetWhitelabelCreateInteractions() func(*gin.Context) { commands, _ := cm.BuildCreatePayload(true, nil) - if _, err = rest.ModifyGlobalCommands(bot.Token, botContext.RateLimiter, bot.BotId, commands); err == nil { + // TODO: Use proper context + if _, err = rest.ModifyGlobalCommands(context.Background(), bot.Token, botContext.RateLimiter, bot.BotId, commands); err == nil { ctx.JSON(200, utils.SuccessResponse) } else { ctx.JSON(500, utils.ErrorJson(err)) diff --git a/app/http/endpoints/api/whitelabel/whitelabelgetguilds.go b/app/http/endpoints/api/whitelabel/whitelabelgetguilds.go index 723a818..5b856dc 100644 --- a/app/http/endpoints/api/whitelabel/whitelabelgetguilds.go +++ b/app/http/endpoints/api/whitelabel/whitelabelgetguilds.go @@ -1,10 +1,13 @@ package api import ( + "context" + "errors" "github.com/TicketsBot/GoPanel/database" "github.com/TicketsBot/GoPanel/rpc/cache" "github.com/TicketsBot/GoPanel/utils" "github.com/gin-gonic/gin" + cache2 "github.com/rxdn/gdl/cache" "strconv" ) @@ -35,9 +38,18 @@ func WhitelabelGetGuilds(ctx *gin.Context) { for _, id := range ids { // get guild name - if guild, found := cache.Instance.GetGuild(id); found { - guilds[strconv.FormatUint(id, 10)] = guild.Name + // TODO: Use proper context + guild, err := cache.Instance.GetGuild(context.Background(), id) + if err != nil { + if errors.Is(err, cache2.ErrNotFound) { + continue + } else { + ctx.JSON(500, utils.ErrorJson(err)) + return + } } + + guilds[strconv.FormatUint(id, 10)] = guild.Name } ctx.JSON(200, gin.H{ diff --git a/app/http/endpoints/api/whitelabel/whitelabelpost.go b/app/http/endpoints/api/whitelabel/whitelabelpost.go index 939977e..a946edd 100644 --- a/app/http/endpoints/api/whitelabel/whitelabelpost.go +++ b/app/http/endpoints/api/whitelabel/whitelabelpost.go @@ -1,6 +1,7 @@ package api import ( + "context" "encoding/base64" dbclient "github.com/TicketsBot/GoPanel/database" "github.com/TicketsBot/GoPanel/redis" @@ -38,7 +39,8 @@ func WhitelabelPost(ctx *gin.Context) { } // Validate token + get bot ID - bot, err := rest.GetCurrentUser(token, nil) + // TODO: Use proper context + bot, err := rest.GetCurrentUser(context.Background(), token, nil) if err != nil { ctx.JSON(400, utils.ErrorJson(err)) return diff --git a/app/http/endpoints/root/callback.go b/app/http/endpoints/root/callback.go index 2aff41d..c079b3c 100644 --- a/app/http/endpoints/root/callback.go +++ b/app/http/endpoints/root/callback.go @@ -1,6 +1,7 @@ package root import ( + "context" "fmt" "github.com/TicketsBot/GoPanel/app/http/session" "github.com/TicketsBot/GoPanel/config" @@ -46,7 +47,7 @@ func CallbackHandler(ctx *gin.Context) { } // Get ID + name - currentUser, err := rest.GetCurrentUser(fmt.Sprintf("Bearer %s", res.AccessToken), nil) + currentUser, err := rest.GetCurrentUser(context.Background(), fmt.Sprintf("Bearer %s", res.AccessToken), nil) if err != nil { ctx.JSON(500, utils.ErrorJson(err)) return @@ -54,7 +55,7 @@ func CallbackHandler(ctx *gin.Context) { store := session.SessionData{ AccessToken: res.AccessToken, - Expiry: (time.Now().UnixNano()/int64(time.Second))+int64(res.ExpiresIn), + Expiry: (time.Now().UnixNano() / int64(time.Second)) + int64(res.ExpiresIn), RefreshToken: res.RefreshToken, Name: currentUser.Username, Avatar: currentUser.AvatarUrl(256), @@ -69,7 +70,7 @@ func CallbackHandler(ctx *gin.Context) { } token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ - "userid": strconv.FormatUint(currentUser.Id, 10), + "userid": strconv.FormatUint(currentUser.Id, 10), "timestamp": time.Now(), }) @@ -86,6 +87,6 @@ func CallbackHandler(ctx *gin.Context) { ctx.JSON(200, gin.H{ "success": true, - "token": str, + "token": str, }) } diff --git a/app/http/middleware/authenticateguild.go b/app/http/middleware/authenticateguild.go index f749b9f..f48889d 100644 --- a/app/http/middleware/authenticateguild.go +++ b/app/http/middleware/authenticateguild.go @@ -1,10 +1,13 @@ package middleware import ( + "context" + "errors" "github.com/TicketsBot/GoPanel/rpc/cache" "github.com/TicketsBot/GoPanel/utils" "github.com/TicketsBot/common/permission" "github.com/gin-gonic/gin" + cache2 "github.com/rxdn/gdl/cache" "strconv" ) @@ -22,17 +25,24 @@ func AuthenticateGuild(requiredPermissionLevel permission.PermissionLevel) gin.H ctx.Keys["guildid"] = parsed // TODO: Do we need this? Only really serves as a check whether the bot is in the server - _, found := cache.Instance.GetGuildOwner(parsed) - if !found { - ctx.JSON(404, utils.ErrorStr("Guild not found")) - ctx.Abort() + // TODO: Use proper context + if _, err := cache.Instance.GetGuildOwner(context.Background(), parsed); err != nil { + if errors.Is(err, cache2.ErrNotFound) { + ctx.JSON(404, utils.ErrorStr("Guild not found")) + ctx.Abort() + } else { + ctx.JSON(500, utils.ErrorJson(err)) + ctx.Abort() + } + return } // Verify the user has permissions to be here userId := ctx.Keys["userid"].(uint64) - permLevel, err := utils.GetPermissionLevel(parsed, userId) + // TODO: Use proper context + permLevel, err := utils.GetPermissionLevel(context.Background(), parsed, userId) if err != nil { ctx.JSON(500, utils.ErrorJson(err)) ctx.Abort() diff --git a/botcontext/botcontext.go b/botcontext/botcontext.go index 27430c0..642962c 100644 --- a/botcontext/botcontext.go +++ b/botcontext/botcontext.go @@ -1,13 +1,16 @@ package botcontext import ( + "context" + "errors" "github.com/TicketsBot/GoPanel/config" dbclient "github.com/TicketsBot/GoPanel/database" "github.com/TicketsBot/GoPanel/redis" - "github.com/TicketsBot/GoPanel/rpc/cache" + cacheclient "github.com/TicketsBot/GoPanel/rpc/cache" "github.com/TicketsBot/common/permission" "github.com/TicketsBot/common/restcache" "github.com/TicketsBot/database" + cache "github.com/rxdn/gdl/cache" "github.com/rxdn/gdl/objects/channel" "github.com/rxdn/gdl/objects/guild" "github.com/rxdn/gdl/objects/guild/emoji" @@ -25,15 +28,15 @@ type BotContext struct { RestCache restcache.RestCache } -func (ctx BotContext) Db() *database.Database { +func (c *BotContext) Db() *database.Database { return dbclient.Client } -func (ctx BotContext) Cache() permission.PermissionCache { +func (c *BotContext) Cache() permission.PermissionCache { return permission.NewRedisCache(redis.Client.Client) } -func (ctx BotContext) IsBotAdmin(userId uint64) bool { +func (c *BotContext) IsBotAdmin(userId uint64) bool { for _, id := range config.Conf.Admins { if id == userId { return true @@ -43,150 +46,219 @@ func (ctx BotContext) IsBotAdmin(userId uint64) bool { return false } -func (ctx BotContext) GetGuild(guildId uint64) (g guild.Guild, err error) { - if guild, found := cache.Instance.GetGuild(guildId); found { - return guild, nil - } +func (c *BotContext) GetGuild(ctx context.Context, guildId uint64) (guild.Guild, error) { + g, err := cacheclient.Instance.GetGuild(ctx, guildId) + switch { + case err == nil: + return g, nil + case errors.Is(err, cache.ErrNotFound): + g, err := rest.GetGuild(ctx, c.Token, c.RateLimiter, guildId) + if err == nil { + if err := cacheclient.Instance.StoreGuild(ctx, g); err != nil { + return guild.Guild{}, err + } + } - g, err = rest.GetGuild(ctx.Token, ctx.RateLimiter, guildId) - if err == nil { - go cache.Instance.StoreGuild(g) + return g, err + default: + return guild.Guild{}, err } - - return } -func (ctx BotContext) GetGuildOwner(guildId uint64) (uint64, error) { - cachedOwner, exists := cache.Instance.GetGuildOwner(guildId) - if exists { +func (c *BotContext) GetGuildOwner(guildId uint64) (uint64, error) { + cachedOwner, err := cacheclient.Instance.GetGuildOwner(context.Background(), guildId) + switch { + case err == nil: return cachedOwner, nil - } + case errors.Is(err, cache.ErrNotFound): + guild, err := c.GetGuild(context.Background(), guildId) + if err != nil { + return 0, err + } - guild, err := ctx.GetGuild(guildId) - if err != nil { + if err := cacheclient.Instance.StoreGuild(context.Background(), guild); err != nil { + return 0, err + } + + return guild.OwnerId, nil + default: return 0, err } - - go cache.Instance.StoreGuild(guild) - return guild.OwnerId, nil } -func (ctx BotContext) GetGuildMember(guildId, userId uint64) (m member.Member, err error) { - if guild, found := cache.Instance.GetMember(guildId, userId); found { - return guild, nil +func (c *BotContext) GetGuildMember(ctx context.Context, guildId, userId uint64) (member.Member, error) { + m, err := cacheclient.Instance.GetMember(ctx, guildId, userId) + switch { + case err == nil: + return m, nil + case errors.Is(err, cache.ErrNotFound): + m, err := rest.GetGuildMember(ctx, c.Token, c.RateLimiter, guildId, userId) + if err != nil { + return member.Member{}, nil + } + + if err := cacheclient.Instance.StoreMember(ctx, m, guildId); err != nil { + return member.Member{}, err + } + + return m, nil + default: + return member.Member{}, err + } +} + +func (c *BotContext) RemoveGuildMemberRole(ctx context.Context, guildId, userId, roleId uint64) error { + return rest.RemoveGuildMemberRole(ctx, c.Token, c.RateLimiter, guildId, userId, roleId) +} + +func (c *BotContext) CreateGuildRole(ctx context.Context, guildId uint64, data rest.GuildRoleData) (guild.Role, error) { + return rest.CreateGuildRole(ctx, c.Token, c.RateLimiter, guildId, data) +} + +func (c *BotContext) DeleteGuildRole(ctx context.Context, guildId, roleId uint64) error { + return rest.DeleteGuildRole(ctx, c.Token, c.RateLimiter, guildId, roleId) +} + +func (c *BotContext) GetUser(ctx context.Context, userId uint64) (user.User, error) { + u, err := cacheclient.Instance.GetUser(ctx, userId) + switch { + case err == nil: + return u, nil + case errors.Is(err, cache.ErrNotFound): + u, err := rest.GetUser(ctx, c.Token, c.RateLimiter, userId) + if err != nil { + return user.User{}, err + } + + if err := cacheclient.Instance.StoreUser(ctx, u); err != nil { + return user.User{}, err + } + + return u, nil + default: + return user.User{}, err + } +} + +func (c *BotContext) GetGuildRoles(ctx context.Context, guildId uint64) ([]guild.Role, error) { + return c.RestCache.GetGuildRoles(guildId) +} + +func (c *BotContext) GetGuildChannels(ctx context.Context, guildId uint64) ([]channel.Channel, error) { + cachedChannels, err := cacheclient.Instance.GetGuildChannels(ctx, guildId) + if err != nil { + return nil, err } - m, err = rest.GetGuildMember(ctx.Token, ctx.RateLimiter, guildId, userId) - if err == nil { - go cache.Instance.StoreMember(m, guildId) - } - - return -} - -func (ctx BotContext) RemoveGuildMemberRole(guildId, userId, roleId uint64) (err error) { - err = rest.RemoveGuildMemberRole(ctx.Token, ctx.RateLimiter, guildId, userId, roleId) - return -} - -func (ctx BotContext) CreateGuildRole(guildId uint64, data rest.GuildRoleData) (role guild.Role, err error) { - role, err = rest.CreateGuildRole(ctx.Token, ctx.RateLimiter, guildId, data) - return -} - -func (ctx BotContext) DeleteGuildRole(guildId, roleId uint64) (err error) { - err = rest.DeleteGuildRole(ctx.Token, ctx.RateLimiter, guildId, roleId) - return -} - -func (ctx BotContext) GetUser(userId uint64) (u user.User, err error) { - u, err = rest.GetUser(ctx.Token, ctx.RateLimiter, userId) - if err == nil { - go cache.Instance.StoreUser(u) - } - - return -} - -func (ctx BotContext) GetGuildRoles(guildId uint64) (roles []guild.Role, err error) { - return ctx.RestCache.GetGuildRoles(guildId) -} - -func (ctx BotContext) GetGuildChannels(guildId uint64) ([]channel.Channel, error) { - cachedChannels := cache.Instance.GetGuildChannels(guildId) - if len(cachedChannels) == 0 { - // If guild is cached but not any channels, likely that it does truly have 0 channels, so don't fetch from REST - _, ok := cache.Instance.GetGuild(guildId) - if ok { + if len(cachedChannels) > 0 { + return cachedChannels, nil + } else { + // If guild is cached but not any channels, likely that it does truly have 0 channels, + // so don't fetch from REST. + _, err := cacheclient.Instance.GetGuild(ctx, guildId) + switch { + case err == nil: return []channel.Channel{}, nil + case errors.Is(err, cache.ErrNotFound): + // If guild isn't cached, fetch from REST + channels, err := rest.GetGuildChannels(ctx, c.Token, c.RateLimiter, guildId) + if err != nil { + return nil, err + } + + if err := cacheclient.Instance.StoreChannels(ctx, channels); err != nil { + return nil, err + } + + return channels, nil + default: + return nil, err } } - - channels, err := rest.GetGuildChannels(ctx.Token, ctx.RateLimiter, guildId) - if err == nil { - go cache.Instance.StoreChannels(channels) - } - - return channels, err } -func (ctx BotContext) GetGuildEmoji(guildId, emojiId uint64) (emoji.Emoji, error) { - if emoji, ok := cache.Instance.GetEmoji(guildId); ok { - return emoji, nil - } +func (c *BotContext) GetGuildEmoji(ctx context.Context, guildId, emojiId uint64) (emoji.Emoji, error) { + e, err := cacheclient.Instance.GetEmoji(ctx, guildId) + switch { + case err == nil: + return e, nil + case errors.Is(err, cache.ErrNotFound): + e, err := rest.GetGuildEmoji(ctx, c.Token, c.RateLimiter, guildId, emojiId) + if err != nil { + return emoji.Emoji{}, err + } - emoji, err := rest.GetGuildEmoji(ctx.Token, ctx.RateLimiter, guildId, emojiId) - if err == nil { - go cache.Instance.StoreEmoji(emoji, guildId) - } + if err := cacheclient.Instance.StoreEmoji(ctx, e, guildId); err != nil { + return emoji.Emoji{}, err + } - return emoji, err + return e, nil + default: + return emoji.Emoji{}, err + } } -func (ctx BotContext) GetGuildEmojis(guildId uint64) (emojis []emoji.Emoji, err error) { - if emojis := cache.Instance.GetGuildEmojis(guildId); len(emojis) > 0 { - return emojis, nil +func (c *BotContext) GetGuildEmojis(ctx context.Context, guildId uint64) ([]emoji.Emoji, error) { + emojis, err := cacheclient.Instance.GetGuildEmojis(ctx, guildId) + if err != nil { + return nil, err } - emojis, err = rest.ListGuildEmojis(ctx.Token, ctx.RateLimiter, guildId) - if err == nil { - go cache.Instance.StoreEmojis(emojis, guildId) + if len(emojis) == 0 { + emojis, err := rest.ListGuildEmojis(ctx, c.Token, c.RateLimiter, guildId) + if err != nil { + return nil, err + } + + if err := cacheclient.Instance.StoreEmojis(ctx, emojis, guildId); err != nil { + return nil, err + } + + return emojis, err } - return + return emojis, nil } -func (ctx BotContext) SearchMembers(guildId uint64, query string) (members []member.Member, err error) { +func (c *BotContext) SearchMembers(ctx context.Context, guildId uint64, query string) ([]member.Member, error) { data := rest.SearchGuildMembersData{ Query: query, Limit: 100, } - members, err = rest.SearchGuildMembers(ctx.Token, ctx.RateLimiter, guildId, data) - if err == nil { - go cache.Instance.StoreMembers(members, guildId) + members, err := rest.SearchGuildMembers(ctx, c.Token, c.RateLimiter, guildId, data) + if err != nil { + return nil, err } - return + if err := cacheclient.Instance.StoreMembers(ctx, members, guildId); err != nil { + return nil, err + } + + return members, nil } -func (ctx BotContext) ListMembers(guildId uint64) (members []member.Member, err error) { +func (c *BotContext) ListMembers(ctx context.Context, guildId uint64) ([]member.Member, error) { data := rest.ListGuildMembersData{ Limit: 100, } - members, err = rest.ListGuildMembers(ctx.Token, ctx.RateLimiter, guildId, data) - if err == nil { - go cache.Instance.StoreMembers(members, guildId) + members, err := rest.ListGuildMembers(ctx, c.Token, c.RateLimiter, guildId, data) + if err != nil { + return nil, err } - return + if err := cacheclient.Instance.StoreMembers(ctx, members, guildId); err != nil { + return nil, err + } + + return members, nil } -func (ctx BotContext) CreateGuildCommand(guildId uint64, data rest.CreateCommandData) (interaction.ApplicationCommand, error) { - return rest.CreateGuildCommand(ctx.Token, ctx.RateLimiter, ctx.BotId, guildId, data) +func (c *BotContext) CreateGuildCommand(ctx context.Context, guildId uint64, data rest.CreateCommandData) (interaction.ApplicationCommand, error) { + return rest.CreateGuildCommand(ctx, c.Token, c.RateLimiter, c.BotId, guildId, data) } -func (ctx BotContext) DeleteGuildCommand(guildId, commandId uint64) error { - return rest.DeleteGuildCommand(ctx.Token, ctx.RateLimiter, ctx.BotId, guildId, commandId) +func (c *BotContext) DeleteGuildCommand(ctx context.Context, guildId, commandId uint64) error { + return rest.DeleteGuildCommand(ctx, c.Token, c.RateLimiter, c.BotId, guildId, commandId) } diff --git a/botcontext/get.go b/botcontext/get.go index fa26133..595fc9d 100644 --- a/botcontext/get.go +++ b/botcontext/get.go @@ -9,21 +9,21 @@ import ( "github.com/rxdn/gdl/rest/ratelimit" ) -func ContextForGuild(guildId uint64) (ctx BotContext, err error) { +func ContextForGuild(guildId uint64) (*BotContext, error) { whitelabelBotId, isWhitelabel, err := dbclient.Client.WhitelabelGuilds.GetBotByGuild(guildId) if err != nil { - return + return nil, err } if isWhitelabel { res, err := dbclient.Client.Whitelabel.GetByBotId(whitelabelBotId) if err != nil { - return ctx, err + return nil, err } rateLimiter := ratelimit.NewRateLimiter(ratelimit.NewRedisStore(redis.Client.Client, fmt.Sprintf("ratelimiter:%d", whitelabelBotId)), 1) - return BotContext{ + return &BotContext{ BotId: res.BotId, Token: res.Token, RateLimiter: rateLimiter, @@ -34,10 +34,10 @@ func ContextForGuild(guildId uint64) (ctx BotContext, err error) { } } -func PublicContext() BotContext { +func PublicContext() *BotContext { rateLimiter := ratelimit.NewRateLimiter(ratelimit.NewRedisStore(redis.Client.Client, "ratelimiter:public"), 1) - return BotContext{ + return &BotContext{ BotId: config.Conf.Bot.Id, Token: config.Conf.Bot.Token, RateLimiter: rateLimiter, diff --git a/frontend/src/components/manage/SettingsCard.svelte b/frontend/src/components/manage/SettingsCard.svelte index 105d036..5ef1279 100644 --- a/frontend/src/components/manage/SettingsCard.svelte +++ b/frontend/src/components/manage/SettingsCard.svelte @@ -22,6 +22,7 @@ + diff --git a/go.mod b/go.mod index 81517fd..6802d05 100644 --- a/go.mod +++ b/go.mod @@ -1,14 +1,16 @@ module github.com/TicketsBot/GoPanel -go 1.18 +go 1.21 + +toolchain go1.22.4 require ( github.com/BurntSushi/toml v1.2.1 - github.com/TicketsBot/archiverclient v0.0.0-20220326163414-558fd52746dc - github.com/TicketsBot/common v0.0.0-20230819234541-7678a70af5f1 - github.com/TicketsBot/database v0.0.0-20230913010851-15cd49b12133 + github.com/TicketsBot/archiverclient v0.0.0-20240613013458-accc062facc2 + github.com/TicketsBot/common v0.0.0-20240613013221-1e27eb8bfe37 + github.com/TicketsBot/database v0.0.0-20240614143550-e9b219d41743 github.com/TicketsBot/logarchiver v0.0.0-20220326162808-cdf0310f5e1c - github.com/TicketsBot/worker v0.0.0-20230913011504-268527c33489 + github.com/TicketsBot/worker v0.0.0-20240615173640-85185c239fd0 github.com/apex/log v1.1.2 github.com/getsentry/sentry-go v0.24.0 github.com/gin-gonic/contrib v0.0.0-20191209060500-d6e26eeaa607 @@ -18,25 +20,26 @@ require ( github.com/go-redis/redis/v8 v8.11.5 github.com/go-redis/redis_rate/v9 v9.1.1 github.com/golang-jwt/jwt v3.2.2+incompatible - github.com/google/uuid v1.3.0 + github.com/google/uuid v1.6.0 github.com/gorilla/websocket v1.5.0 - github.com/jackc/pgconn v1.14.1 + github.com/jackc/pgconn v1.14.3 github.com/jackc/pgtype v1.14.0 - github.com/jackc/pgx/v4 v4.18.1 + github.com/jackc/pgx/v4 v4.18.3 github.com/pasztorpisti/qs v0.0.0-20171216220353-8d6c33ee906c github.com/penglongli/gin-metrics v0.1.10 github.com/pkg/errors v0.9.1 - github.com/rxdn/gdl v0.0.0-20230716201318-bd66d6307f3b + github.com/prometheus/client_golang v1.14.0 + github.com/rxdn/gdl v0.0.0-20240617014237-c4fad8528038 github.com/sirupsen/logrus v1.9.3 - github.com/stretchr/testify v1.8.3 + github.com/stretchr/testify v1.8.4 github.com/weppos/publicsuffix-go v0.20.0 - golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7 + golang.org/x/sync v0.7.0 ) require ( github.com/ClickHouse/ch-go v0.52.1 // indirect github.com/ClickHouse/clickhouse-go/v2 v2.10.0 // indirect - github.com/TicketsBot/analytics-client v0.0.0-20230607214124-b2b1f3643e8e // indirect + github.com/TicketsBot/analytics-client v0.0.0-20240415004242-017c23403af3 // indirect github.com/TicketsBot/ttlcache v1.6.1-0.20200405150101-acc18e37b261 // indirect github.com/andybalholm/brotli v1.0.5 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -57,28 +60,32 @@ require ( github.com/go-faster/errors v0.6.1 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-redsync/redsync/v4 v4.12.1 // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/gofrs/uuid v4.0.0+incompatible // indirect - github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/protobuf v1.5.4 // indirect github.com/gomodule/redigo v2.0.0+incompatible // indirect github.com/gorilla/context v1.1.1 // indirect github.com/gorilla/securecookie v1.1.1 // indirect github.com/gorilla/sessions v1.2.1 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/jackc/chunkreader/v2 v2.0.1 // indirect github.com/jackc/pgio v1.0.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect - github.com/jackc/pgproto3/v2 v2.3.2 // indirect + github.com/jackc/pgproto3/v2 v2.3.3 // indirect github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect github.com/jackc/pgx v3.6.2+incompatible // indirect github.com/jackc/puddle v1.3.0 // indirect + github.com/jedib0t/go-pretty/v6 v6.5.6 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/juju/ratelimit v1.0.2 // indirect github.com/klauspost/compress v1.16.0 // indirect github.com/klauspost/cpuid/v2 v2.2.4 // indirect github.com/leodido/go-urn v1.2.4 // indirect github.com/mattn/go-isatty v0.0.19 // indirect - github.com/mattn/go-runewidth v0.0.13 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect @@ -86,29 +93,31 @@ require ( github.com/pelletier/go-toml/v2 v2.0.8 // indirect github.com/pierrec/lz4/v4 v4.1.17 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_golang v1.12.2 // indirect - github.com/prometheus/client_model v0.2.0 // indirect - github.com/prometheus/common v0.32.1 // indirect - github.com/prometheus/procfs v0.7.3 // indirect + github.com/prometheus/client_model v0.3.0 // indirect + github.com/prometheus/common v0.37.0 // indirect + github.com/prometheus/procfs v0.8.0 // indirect github.com/rivo/uniseg v0.2.0 // indirect + github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/schollz/progressbar/v3 v3.8.2 // indirect github.com/segmentio/asm v1.2.0 // indirect github.com/shopspring/decimal v1.3.1 // indirect github.com/tatsuworks/czlib v0.0.0-20190916144400-8a51758ea0d9 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.11 // indirect - go.opentelemetry.io/otel v1.13.0 // indirect - go.opentelemetry.io/otel/trace v1.13.0 // indirect + go.opentelemetry.io/otel v1.19.0 // indirect + go.opentelemetry.io/otel/trace v1.19.0 // indirect go.uber.org/atomic v1.10.0 // indirect golang.org/x/arch v0.3.0 // indirect - golang.org/x/crypto v0.11.0 // indirect + golang.org/x/crypto v0.24.0 // indirect golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect - golang.org/x/net v0.12.0 // indirect - golang.org/x/sys v0.10.0 // indirect - golang.org/x/term v0.10.0 // indirect - golang.org/x/text v0.11.0 // indirect - google.golang.org/protobuf v1.30.0 // indirect + golang.org/x/net v0.26.0 // indirect + golang.org/x/sys v0.21.0 // indirect + golang.org/x/term v0.21.0 // indirect + golang.org/x/text v0.16.0 // indirect + google.golang.org/protobuf v1.33.0 // indirect gopkg.in/alexcesaro/statsd.v2 v2.0.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect nhooyr.io/websocket v1.8.4 // indirect ) + +replace github.com/TicketsBot/common => ../common diff --git a/go.sum b/go.sum index bb5a3c5..772d5fc 100644 --- a/go.sum +++ b/go.sum @@ -41,20 +41,18 @@ github.com/ClickHouse/clickhouse-go/v2 v2.10.0 h1:0w/A50D5MfsRUYBaV6rLKwZ4LXWKLZ github.com/ClickHouse/clickhouse-go/v2 v2.10.0/go.mod h1:teXfZNM90iQ99Jnuht+dxQXCuhDZ8nvvMoTJOFrcmcg= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/ReneKroon/ttlcache v1.6.0/go.mod h1:DG6nbhXKUQhrExfwwLuZUdH7UnRDDRA1IW+nBuCssvs= -github.com/TicketsBot/analytics-client v0.0.0-20230607214124-b2b1f3643e8e h1:tIN6AZZS5Zyc4l01kemWu5VRRB0Zc1Nt1LRPgqkqsyc= -github.com/TicketsBot/analytics-client v0.0.0-20230607214124-b2b1f3643e8e/go.mod h1:9Z9qP/yovb6DUe1KlzgN2wicc+8ey6MMoxfynFbMyRg= -github.com/TicketsBot/archiverclient v0.0.0-20220326163414-558fd52746dc h1:n15W8Eg+ik3/0yqPzZVRP2oZJcIZCIgQ071cZleedKo= -github.com/TicketsBot/archiverclient v0.0.0-20220326163414-558fd52746dc/go.mod h1:2KcfHS0JnSsgcxZBs3NyWMXNQzEo67mBSGOyzHPWOCc= -github.com/TicketsBot/common v0.0.0-20230819234541-7678a70af5f1 h1:ulEWPU9i9uNPkduWyUZoIHgaKmoUoLW5LguCD2iXX7U= -github.com/TicketsBot/common v0.0.0-20230819234541-7678a70af5f1/go.mod h1:rZuaTbjajlxscl628aBgUGiUZcOVLvF6pfsPL+2JOac= -github.com/TicketsBot/database v0.0.0-20230913010851-15cd49b12133 h1:YHwa9VFz7XGOh2WhoNJCo27kkLccpKd6myWip86olIs= -github.com/TicketsBot/database v0.0.0-20230913010851-15cd49b12133/go.mod h1:gAtOoQKZfCkQ4AoNWQUSl51Fnlqk+odzD/hZ1e1sXyI= +github.com/TicketsBot/analytics-client v0.0.0-20240415004242-017c23403af3 h1:lSv0RoMTXohcN6yYKsBQftpYnRMZUYdmeFkpEMj6X7A= +github.com/TicketsBot/analytics-client v0.0.0-20240415004242-017c23403af3/go.mod h1:9Z9qP/yovb6DUe1KlzgN2wicc+8ey6MMoxfynFbMyRg= +github.com/TicketsBot/archiverclient v0.0.0-20240613013458-accc062facc2 h1:x2AZWm2zeyIJxVJbq9JQB1Q2mAaaTuCbCiPIU1E8G1o= +github.com/TicketsBot/archiverclient v0.0.0-20240613013458-accc062facc2/go.mod h1:sc1kAppJn1fX6ZCsiU3ltGiXIj9GEZkjkdh8fbmwxWQ= +github.com/TicketsBot/database v0.0.0-20240614143550-e9b219d41743 h1:wTGntdybAv9GcWYE3RJiAIo4I6rYrfG9uSpHaF0KUXY= +github.com/TicketsBot/database v0.0.0-20240614143550-e9b219d41743/go.mod h1:gAtOoQKZfCkQ4AoNWQUSl51Fnlqk+odzD/hZ1e1sXyI= github.com/TicketsBot/logarchiver v0.0.0-20220326162808-cdf0310f5e1c h1:OqGjFH6mbE6gd+NqI2ARJdtH3UUvhiAkD0r0fhGJK2s= github.com/TicketsBot/logarchiver v0.0.0-20220326162808-cdf0310f5e1c/go.mod h1:jgi2OXQKsd5nUnTIRkwvPmeuD/i7OhN68LKMssuQY1c= github.com/TicketsBot/ttlcache v1.6.1-0.20200405150101-acc18e37b261 h1:NHD5GB6cjlkpZFjC76Yli2S63/J2nhr8MuE6KlYJpQM= github.com/TicketsBot/ttlcache v1.6.1-0.20200405150101-acc18e37b261/go.mod h1:2zPxDAN2TAPpxUPjxszjs3QFKreKrQh5al/R3cMXmYk= -github.com/TicketsBot/worker v0.0.0-20230913011504-268527c33489 h1:usE+mwjUBZ43truAqeH2/AISRCYkB5wLyWZojcyho34= -github.com/TicketsBot/worker v0.0.0-20230913011504-268527c33489/go.mod h1:GSQxOsd1HS5tQE2tqGAdYUwZsIDOaYYsLBgNI+fRZ08= +github.com/TicketsBot/worker v0.0.0-20240615173640-85185c239fd0 h1:fJGZTemsOHKojbcUbRN9v/fbHNHWby67OHcXeBp5tsQ= +github.com/TicketsBot/worker v0.0.0-20240615173640-85185c239fd0/go.mod h1:ITT/KqRR1qPcrCFhsJlFiRoHen9yI2i7wFdjZQGDIQs= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -115,8 +113,9 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/getsentry/sentry-go v0.24.0 h1:02b7qEmJ56EHGe9KFgjArjU/vG/aywm7Efgu+iPc01Y= @@ -140,11 +139,14 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= @@ -156,11 +158,15 @@ github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg= github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= +github.com/go-redis/redis/v7 v7.4.0 h1:7obg6wUoj05T0EpY0o8B59S9w5yeMWql7sw2kwNW1x4= +github.com/go-redis/redis/v7 v7.4.0/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg= github.com/go-redis/redis/v8 v8.3.4/go.mod h1:jszGxBCez8QA1HWSmQxJO9Y82kNibbUmeYhKWrBejTU= github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/go-redis/redis_rate/v9 v9.1.1 h1:7SIrbnhQ7zsTNEgIvprFhJf7/+l3wSpZc2iRVwUmaq8= github.com/go-redis/redis_rate/v9 v9.1.1/go.mod h1:jjU9YxOSZ3cz0yj1QJVAJiy5ueKmL9o4AySJHcKyTSE= +github.com/go-redsync/redsync/v4 v4.12.1 h1:hCtdZ45DJxMxNdPiby5GlQwOKQmcka2587Y466qPqlA= +github.com/go-redsync/redsync/v4 v4.12.1/go.mod h1:sn72ojgeEhxUuRjrliK0NRrB0Zl6kOZ3BDvNN3P2jAY= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= @@ -202,8 +208,9 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0= github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= @@ -220,6 +227,7 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -234,8 +242,8 @@ github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8= @@ -248,6 +256,11 @@ github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/z github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= @@ -262,9 +275,8 @@ github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsU github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY= github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= -github.com/jackc/pgconn v1.14.0/go.mod h1:9mBNlny0UvkgJdCDvdVHYSjI+8tD2rnKK69Wz8ti++E= -github.com/jackc/pgconn v1.14.1 h1:smbxIaZA08n6YuxEX1sDyjV/qkbtUtkH20qLkR9MUR4= -github.com/jackc/pgconn v1.14.1/go.mod h1:9mBNlny0UvkgJdCDvdVHYSjI+8tD2rnKK69Wz8ti++E= +github.com/jackc/pgconn v1.14.3 h1:bVoTr12EGANZz66nZPkMInAV/KHD2TxH9npjXXgiB3w= +github.com/jackc/pgconn v1.14.3/go.mod h1:RZbme4uasqzybK2RK5c65VsHxoyaml09lx3tXOcO/VM= github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= @@ -280,8 +292,8 @@ github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvW github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgproto3/v2 v2.3.2 h1:7eY55bdBeCz1F2fTzSz69QC+pG46jYq9/jtSPiJ5nn0= -github.com/jackc/pgproto3/v2 v2.3.2/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.3.3 h1:1HLSx5H+tXR9pW3in3zaztoEwQYRC9SQaYUHjTSUOag= +github.com/jackc/pgproto3/v2 v2.3.3/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= @@ -297,13 +309,15 @@ github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08 github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= -github.com/jackc/pgx/v4 v4.18.1 h1:YP7G1KABtKpB5IHrO9vYwSrCOhs7p3uqhvhhQBptya0= -github.com/jackc/pgx/v4 v4.18.1/go.mod h1:FydWkUyadDmdNH/mHnGob881GawxeEm7TcMCzkb+qQE= +github.com/jackc/pgx/v4 v4.18.3 h1:dE2/TrEsGX3RBprb3qryqSV9Y60iZN1C6i8IrmW9/BA= +github.com/jackc/pgx/v4 v4.18.3/go.mod h1:Ey4Oru5tH5sB6tV7hDmfWFahwF15Eb7DNXlRKx2CkVw= github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.3.0 h1:eHK/5clGOatcjX3oWGBO/MpxpbHzSwud5EWTSCI+MX0= github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jedib0t/go-pretty/v6 v6.5.6 h1:nKXVLqPfAwY7sWcYXdNZZZ2fjqDpAtj9UeWupgfUxSg= +github.com/jedib0t/go-pretty/v6 v6.5.6/go.mod h1:5LQIxa52oJ/DlDSLv0HEkWOFMDGoWkJb9ss5KqPpJBg= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= @@ -334,6 +348,8 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxv github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= @@ -356,10 +372,12 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= @@ -373,18 +391,20 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= +github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= github.com/pasztorpisti/qs v0.0.0-20171216220353-8d6c33ee906c h1:Gcce/r5tSQeprxswXXOwQ/RBU1bjQWVd9dB7QKoPXBE= github.com/pasztorpisti/qs v0.0.0-20171216220353-8d6c33ee906c/go.mod h1:1iCZ0433JJMecYqCa+TdWA9Pax8MGl4ByuNDZ7eSnQY= github.com/paulmach/orb v0.9.0 h1:MwA1DqOKtvCgm7u9RZ/pnYejTeDJPnr0+0oFajBbJqk= @@ -397,6 +417,7 @@ github.com/penglongli/gin-metrics v0.1.10/go.mod h1:wxGsGUwpVGv3hmYSxQn2GZgRL3Yu github.com/pierrec/lz4/v4 v4.1.17 h1:kV4Ip+/hUBC+8T6+2EgburRtkE9ef4nbY3f4dFhGjMc= github.com/pierrec/lz4/v4 v4.1.17/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= +github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -408,33 +429,43 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.12.0/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_golang v1.12.2 h1:51L9cDoUHVrXx4zWYlcLQIZ+d+VXHgqnYKkIuq4g/34= -github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= +github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= +github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= +github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= +github.com/redis/go-redis/v9 v9.4.0 h1:Yzoz33UZw9I/mFhx4MNrB6Fk+XHO1VukNcCa1+lwyKk= +github.com/redis/go-redis/v9 v9.4.0/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M= +github.com/redis/rueidis v1.0.19 h1:s65oWtotzlIFN8eMPhyYwxlwLR1lUdhza2KtWprKYSo= +github.com/redis/rueidis v1.0.19/go.mod h1:8B+r5wdnjwK3lTFml5VtxjzGOQAC+5UmujoD12pDrEo= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/fastuuid v1.1.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= -github.com/rxdn/gdl v0.0.0-20230716201318-bd66d6307f3b h1:tuyxHFPgLuodjX6R5fEDns9EzQa88u9QUZlLxGw9vY0= -github.com/rxdn/gdl v0.0.0-20230716201318-bd66d6307f3b/go.mod h1:HtxfLp4OaoPoDJHQ4JOx/QeLH2d40VgT3wNOf7ETsRE= +github.com/rxdn/gdl v0.0.0-20240617014237-c4fad8528038 h1:BODM7TvQX1cP52qoeG9EuC1l631LrgngqXsNTE1urZg= +github.com/rxdn/gdl v0.0.0-20240617014237-c4fad8528038/go.mod h1:HtxfLp4OaoPoDJHQ4JOx/QeLH2d40VgT3wNOf7ETsRE= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/schollz/progressbar/v3 v3.8.2 h1:2kZJwZCpb+E/V79kGO7daeq+hUwUJW0A5QD1Wv455dA= github.com/schollz/progressbar/v3 v3.8.2/go.mod h1:9KHLdyuXczIsyStQwzvW8xiELskmX7fQMaZdN23nAv8= @@ -469,8 +500,11 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stvp/tempredis v0.0.0-20181119212430-b82af8480203 h1:QVqDTf3h2WHt08YuiTGPZLls0Wq99X9bWd0Q5ZSBesM= +github.com/stvp/tempredis v0.0.0-20181119212430-b82af8480203/go.mod h1:oqN97ltKNihBbwlX8dLpwxCl3+HnXKV/R0e+sRLd9C8= github.com/tatsuworks/czlib v0.0.0-20190916144400-8a51758ea0d9 h1:i2aD44Moa5N5pt/WNwHLvIklzPymtr8vkkBlVdNElUE= github.com/tatsuworks/czlib v0.0.0-20190916144400-8a51758ea0d9/go.mod h1:6HrfShlf4bKeQEFdWn4JP/yet/mHW2RhxOQf0e3HWA0= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= @@ -496,7 +530,6 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= go.mongodb.org/mongo-driver v1.11.1/go.mod h1:s7p5vEtfbeR1gYi6pnj3c3/urpbLv2T5Sfd6Rp2HBB8= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= @@ -505,18 +538,19 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opentelemetry.io/otel v0.13.0/go.mod h1:dlSNewoRYikTkotEnxdmuBHgzT+k/idJSfDv/FxEnOY= -go.opentelemetry.io/otel v1.13.0 h1:1ZAKnNQKwBBxFtww/GwxNUyTf0AxkZzrukO8MeXqe4Y= -go.opentelemetry.io/otel v1.13.0/go.mod h1:FH3RtdZCzRkJYFTCsAKDy9l/XYjMdNv6QrkFFB8DvVg= -go.opentelemetry.io/otel/trace v1.13.0 h1:CBgRZ6ntv+Amuj1jDsMhZtlAPT6gbyIRdaIzFhfBSdY= -go.opentelemetry.io/otel/trace v1.13.0/go.mod h1:muCvmmO9KKpvuXSf3KKAXXB2ygNYHQ+ZfI5X08d3tds= +go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs= +go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= +go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg= +go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/goleak v0.10.0 h1:G3eWbSNIskeRqtsN/1uI5B+eP73y3JUuBsv9AZjehb4= go.uber.org/goleak v0.10.0/go.mod h1:VCZuO8V8mFPlL0F5J5GK1rtHV3DrFcQ1R8ryq7FK0aI= +go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= +go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= @@ -539,11 +573,9 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= -golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= -golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -576,7 +608,6 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -613,16 +644,17 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= -golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -634,9 +666,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7 h1:ZrnxWX62AgTKOSagEqxvb3ffipvEDX2pl7E1TdqLqIc= -golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -685,22 +716,19 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= -golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= -golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= +golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -709,13 +737,13 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= -golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -763,7 +791,6 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -846,15 +873,16 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alexcesaro/statsd.v2 v2.0.0 h1:FXkZSCZIH17vLCO5sO2UucTHsH9pc+17F6pl3JVCwMc= gopkg.in/alexcesaro/statsd.v2 v2.0.0/go.mod h1:i0ubccKGzBVNBpdGV5MocxyA/XlLUJzA7SLonnE4drU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= diff --git a/utils/guildutils.go b/utils/guildutils.go index 7a44a99..eaa87f4 100644 --- a/utils/guildutils.go +++ b/utils/guildutils.go @@ -1,7 +1,9 @@ package utils import ( + "context" "fmt" + "github.com/TicketsBot/GoPanel/app" dbclient "github.com/TicketsBot/GoPanel/database" "github.com/TicketsBot/database" "github.com/rxdn/gdl/rest" @@ -14,7 +16,10 @@ func LoadGuilds(accessToken string, userId uint64) error { Limit: 200, } - guilds, err := rest.GetCurrentUserGuilds(authHeader, nil, data) + ctx, cancel := context.WithTimeout(context.Background(), app.DefaultTimeout) + defer cancel() + + guilds, err := rest.GetCurrentUserGuilds(ctx, authHeader, nil, data) if err != nil { return err } diff --git a/utils/permissionutils.go b/utils/permissionutils.go index cde81b4..621aef2 100644 --- a/utils/permissionutils.go +++ b/utils/permissionutils.go @@ -1,6 +1,7 @@ package utils import ( + "context" "github.com/TicketsBot/GoPanel/botcontext" dbclient "github.com/TicketsBot/GoPanel/database" "github.com/TicketsBot/GoPanel/internal/api" @@ -10,7 +11,7 @@ import ( "net/http" ) -func GetPermissionLevel(guildId, userId uint64) (permission.PermissionLevel, error) { +func GetPermissionLevel(ctx context.Context, guildId, userId uint64) (permission.PermissionLevel, error) { botContext, err := botcontext.ContextForGuild(guildId) if err != nil { return permission.Everyone, err @@ -40,7 +41,7 @@ func GetPermissionLevel(guildId, userId uint64) (permission.PermissionLevel, err } // get member - member, err := botContext.GetGuildMember(guildId, userId) + member, err := botContext.GetGuildMember(ctx, guildId, userId) if err != nil { return permission.Everyone, err } @@ -49,7 +50,7 @@ func GetPermissionLevel(guildId, userId uint64) (permission.PermissionLevel, err } // TODO: Use this on the ticket list -func HasPermissionToViewTicket(guildId, userId uint64, ticket database.Ticket) (bool, *api.RequestError) { +func HasPermissionToViewTicket(ctx context.Context, guildId, userId uint64, ticket database.Ticket) (bool, *api.RequestError) { // If user opened the ticket, they will always have permission if ticket.UserId == userId && ticket.GuildId == guildId { return true, nil @@ -84,7 +85,7 @@ func HasPermissionToViewTicket(guildId, userId uint64, ticket database.Ticket) ( } // Check if server owner - guild, err := botContext.GetGuild(guildId) + guild, err := botContext.GetGuild(ctx, guildId) if err != nil { return false, api.NewInternalServerError(err, "Error retrieving guild object") } @@ -93,7 +94,7 @@ func HasPermissionToViewTicket(guildId, userId uint64, ticket database.Ticket) ( return true, nil } - member, err := botContext.GetGuildMember(guildId, userId) + member, err := botContext.GetGuildMember(ctx, guildId, userId) if err != nil { return false, api.NewErrorWithMessage(http.StatusForbidden, err, "User not in server: are you logged into the correct account?") }