whitelabel support

This commit is contained in:
Dot-Rar 2020-05-27 19:39:47 +01:00
parent 396cb4ae47
commit 799e6b3389
19 changed files with 238 additions and 187 deletions

View File

@ -2,10 +2,9 @@ package api
import ( import (
"fmt" "fmt"
"github.com/TicketsBot/GoPanel/config" "github.com/TicketsBot/GoPanel/botcontext"
"github.com/TicketsBot/GoPanel/database" "github.com/TicketsBot/GoPanel/database"
"github.com/TicketsBot/GoPanel/rpc/cache" "github.com/TicketsBot/GoPanel/rpc/cache"
"github.com/TicketsBot/GoPanel/rpc/ratelimit"
"github.com/TicketsBot/GoPanel/utils" "github.com/TicketsBot/GoPanel/utils"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/rxdn/gdl/rest" "github.com/rxdn/gdl/rest"
@ -19,6 +18,15 @@ var MentionRegex, _ = regexp.Compile("<@(\\d+)>")
func GetTicket(ctx *gin.Context) { func GetTicket(ctx *gin.Context) {
guildId := ctx.Keys["guildid"].(uint64) guildId := ctx.Keys["guildid"].(uint64)
botContext, err := botcontext.ContextForGuild(guildId)
if err != nil {
ctx.AbortWithStatusJSON(500, gin.H{
"success": false,
"error": err.Error(),
})
return
}
ticketId, err := strconv.Atoi(ctx.Param("ticketId")) ticketId, err := strconv.Atoi(ctx.Param("ticketId"))
if err != nil { if err != nil {
ctx.AbortWithStatusJSON(400, gin.H{ ctx.AbortWithStatusJSON(400, gin.H{
@ -63,7 +71,7 @@ func GetTicket(ctx *gin.Context) {
} }
// Get messages // Get messages
messages, _ := rest.GetChannelMessages(config.Conf.Bot.Token, ratelimit.Ratelimiter, *ticket.ChannelId, rest.GetChannelMessagesData{Limit: 100}) messages, _ := rest.GetChannelMessages(botContext.Token, botContext.RateLimiter, *ticket.ChannelId, rest.GetChannelMessagesData{Limit: 100})
// Format messages, exclude unneeded data // Format messages, exclude unneeded data
messagesFormatted := make([]map[string]interface{}, 0) messagesFormatted := make([]map[string]interface{}, 0)

View File

@ -3,6 +3,7 @@ package api
import ( import (
"github.com/TicketsBot/GoPanel/database" "github.com/TicketsBot/GoPanel/database"
"github.com/TicketsBot/GoPanel/utils" "github.com/TicketsBot/GoPanel/utils"
"github.com/TicketsBot/common/permission"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/rxdn/gdl/objects/guild" "github.com/rxdn/gdl/objects/guild"
) )
@ -36,9 +37,7 @@ func GetGuilds(ctx *gin.Context) {
fakeGuild.OwnerId = userId fakeGuild.OwnerId = userId
} }
isAdmin := make(chan bool) if utils.GetPermissionLevel(g.GuildId, userId) >= permission.Admin {
go utils.IsAdmin(fakeGuild, userId, isAdmin)
if <-isAdmin {
adminGuilds = append(adminGuilds, wrappedGuild{ adminGuilds = append(adminGuilds, wrappedGuild{
Id: g.GuildId, Id: g.GuildId,
Name: g.Name, Name: g.Name,

View File

@ -3,10 +3,9 @@ package api
import ( import (
"context" "context"
"fmt" "fmt"
"github.com/TicketsBot/GoPanel/config" "github.com/TicketsBot/GoPanel/botcontext"
dbclient "github.com/TicketsBot/GoPanel/database" dbclient "github.com/TicketsBot/GoPanel/database"
"github.com/TicketsBot/GoPanel/rpc/cache" "github.com/TicketsBot/GoPanel/rpc/cache"
"github.com/TicketsBot/GoPanel/rpc/ratelimit"
"github.com/TicketsBot/GoPanel/utils" "github.com/TicketsBot/GoPanel/utils"
"github.com/TicketsBot/database" "github.com/TicketsBot/database"
"github.com/apex/log" "github.com/apex/log"
@ -22,6 +21,15 @@ const (
func GetLogs(ctx *gin.Context) { func GetLogs(ctx *gin.Context) {
guildId := ctx.Keys["guildid"].(uint64) guildId := ctx.Keys["guildid"].(uint64)
botContext, err := botcontext.ContextForGuild(guildId)
if err != nil {
ctx.AbortWithStatusJSON(500, gin.H{
"success": false,
"error": err.Error(),
})
return
}
before, err := strconv.Atoi(ctx.Query("before")) before, err := strconv.Atoi(ctx.Query("before"))
if before < 0 { if before < 0 {
before = 0 before = 0
@ -102,7 +110,7 @@ func GetLogs(ctx *gin.Context) {
// get username // get username
user, found := cache.Instance.GetUser(ticket.UserId) user, found := cache.Instance.GetUser(ticket.UserId)
if !found { if !found {
user, err = rest.GetUser(config.Conf.Bot.Token, ratelimit.Ratelimiter, ticket.UserId) user, err = rest.GetUser(botContext.Token, botContext.RateLimiter, ticket.UserId)
if err != nil { if err != nil {
log.Error(err.Error()) log.Error(err.Error())
} }

View File

@ -1,11 +1,10 @@
package api package api
import ( import (
"github.com/TicketsBot/GoPanel/config" "github.com/TicketsBot/GoPanel/botcontext"
dbclient "github.com/TicketsBot/GoPanel/database" dbclient "github.com/TicketsBot/GoPanel/database"
"github.com/TicketsBot/GoPanel/rpc" "github.com/TicketsBot/GoPanel/rpc"
"github.com/TicketsBot/GoPanel/rpc/cache" "github.com/TicketsBot/GoPanel/rpc/cache"
"github.com/TicketsBot/GoPanel/rpc/ratelimit"
"github.com/TicketsBot/GoPanel/utils" "github.com/TicketsBot/GoPanel/utils"
"github.com/TicketsBot/common/premium" "github.com/TicketsBot/common/premium"
"github.com/TicketsBot/database" "github.com/TicketsBot/database"
@ -21,6 +20,16 @@ import (
func CreatePanel(ctx *gin.Context) { func CreatePanel(ctx *gin.Context) {
guildId := ctx.Keys["guildid"].(uint64) guildId := ctx.Keys["guildid"].(uint64)
botContext, err := botcontext.ContextForGuild(guildId)
if err != nil {
ctx.AbortWithStatusJSON(500, gin.H{
"success": false,
"error": err.Error(),
})
return
}
var data panel var data panel
if err := ctx.BindJSON(&data); err != nil { if err := ctx.BindJSON(&data); err != nil {
@ -34,8 +43,7 @@ func CreatePanel(ctx *gin.Context) {
data.MessageId = 0 data.MessageId = 0
// Check panel quota // Check panel quota
// TODO: Whitelabel tokens & ratelimiters premiumTier := rpc.PremiumClient.GetTierByGuildId(guildId, true, botContext.Token, botContext.RateLimiter)
premiumTier := rpc.PremiumClient.GetTierByGuildId(guildId, true, config.Conf.Bot.Token, ratelimit.Ratelimiter)
if premiumTier == premium.None { if premiumTier == premium.None {
panels, err := dbclient.Client.Panel.GetByGuild(guildId) panels, err := dbclient.Client.Panel.GetByGuild(guildId)
@ -59,7 +67,7 @@ func CreatePanel(ctx *gin.Context) {
return return
} }
msgId, err := data.sendEmbed(premiumTier > premium.None) msgId, err := data.sendEmbed(&botContext, premiumTier > premium.None)
if err != nil { if err != nil {
if err == request.ErrForbidden { if err == request.ErrForbidden {
ctx.AbortWithStatusJSON(500, gin.H{ ctx.AbortWithStatusJSON(500, gin.H{
@ -79,7 +87,7 @@ func CreatePanel(ctx *gin.Context) {
// Add reaction // Add reaction
emoji, _ := data.getEmoji() // already validated emoji, _ := data.getEmoji() // already validated
if err = rest.CreateReaction(config.Conf.Bot.Token, ratelimit.Ratelimiter, data.ChannelId, msgId, emoji); err != nil { if err = rest.CreateReaction(botContext.Token, botContext.RateLimiter, data.ChannelId, msgId, emoji); err != nil {
if err == request.ErrForbidden { if err == request.ErrForbidden {
ctx.AbortWithStatusJSON(500, gin.H{ ctx.AbortWithStatusJSON(500, gin.H{
"success": false, "success": false,
@ -208,7 +216,7 @@ func (p *panel) verifyCategory(channels []channel.Channel) bool {
return valid return valid
} }
func (p *panel) sendEmbed(isPremium bool) (messageId uint64, err error) { func (p *panel) sendEmbed(ctx *botcontext.BotContext, isPremium bool) (messageId uint64, err error) {
e := embed.NewEmbed(). e := embed.NewEmbed().
SetTitle(p.Title). SetTitle(p.Title).
SetDescription(p.Content). SetDescription(p.Content).
@ -220,7 +228,7 @@ func (p *panel) sendEmbed(isPremium bool) (messageId uint64, err error) {
} }
var msg message.Message var msg message.Message
msg, err = rest.CreateMessage(config.Conf.Bot.Token, ratelimit.Ratelimiter, p.ChannelId, rest.CreateMessageData{Embed: e}) msg, err = rest.CreateMessage(ctx.Token, ctx.RateLimiter, p.ChannelId, rest.CreateMessageData{Embed: e})
if err != nil { if err != nil {
return return
} }

View File

@ -1,9 +1,8 @@
package api package api
import ( import (
"github.com/TicketsBot/GoPanel/config" "github.com/TicketsBot/GoPanel/botcontext"
"github.com/TicketsBot/GoPanel/database" "github.com/TicketsBot/GoPanel/database"
"github.com/TicketsBot/GoPanel/rpc/ratelimit"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/rxdn/gdl/rest" "github.com/rxdn/gdl/rest"
"strconv" "strconv"
@ -12,6 +11,15 @@ import (
func DeletePanel(ctx *gin.Context) { func DeletePanel(ctx *gin.Context) {
guildId := ctx.Keys["guildid"].(uint64) guildId := ctx.Keys["guildid"].(uint64)
botContext, err := botcontext.ContextForGuild(guildId)
if err != nil {
ctx.AbortWithStatusJSON(500, gin.H{
"success": false,
"error": err.Error(),
})
return
}
messageId, err := strconv.ParseUint(ctx.Param("message"), 10, 64) messageId, err := strconv.ParseUint(ctx.Param("message"), 10, 64)
if err != nil { if err != nil {
ctx.AbortWithStatusJSON(400, gin.H{ ctx.AbortWithStatusJSON(400, gin.H{
@ -47,7 +55,7 @@ func DeletePanel(ctx *gin.Context) {
return return
} }
if err := rest.DeleteMessage(config.Conf.Bot.Token, ratelimit.Ratelimiter, panel.ChannelId, panel.MessageId); err != nil { if err := rest.DeleteMessage(botContext.Token, botContext.RateLimiter, panel.ChannelId, panel.MessageId); err != nil {
ctx.JSON(500, gin.H{ ctx.JSON(500, gin.H{
"success": false, "success": false,
"error": err.Error(), "error": err.Error(),

View File

@ -1,9 +1,8 @@
package api package api
import ( import (
"github.com/TicketsBot/GoPanel/config" "github.com/TicketsBot/GoPanel/botcontext"
"github.com/TicketsBot/GoPanel/rpc" "github.com/TicketsBot/GoPanel/rpc"
"github.com/TicketsBot/GoPanel/rpc/ratelimit"
"github.com/TicketsBot/common/premium" "github.com/TicketsBot/common/premium"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
@ -11,8 +10,16 @@ import (
func PremiumHandler(ctx *gin.Context) { func PremiumHandler(ctx *gin.Context) {
guildId := ctx.Keys["guildid"].(uint64) guildId := ctx.Keys["guildid"].(uint64)
// TODO: Whitelabel tokens & ratelimiters botContext, err := botcontext.ContextForGuild(guildId)
premiumTier := rpc.PremiumClient.GetTierByGuildId(guildId, true, config.Conf.Bot.Token, ratelimit.Ratelimiter) if err != nil {
ctx.AbortWithStatusJSON(500, gin.H{
"success": false,
"error": err.Error(),
})
return
}
premiumTier := rpc.PremiumClient.GetTierByGuildId(guildId, true, botContext.Token, botContext.RateLimiter)
ctx.JSON(200, gin.H{ ctx.JSON(200, gin.H{
"premium": premiumTier >= premium.Premium, "premium": premiumTier >= premium.Premium,

View File

@ -2,11 +2,10 @@ package api
import ( import (
"fmt" "fmt"
"github.com/TicketsBot/GoPanel/config" "github.com/TicketsBot/GoPanel/botcontext"
"github.com/TicketsBot/GoPanel/database" "github.com/TicketsBot/GoPanel/database"
"github.com/TicketsBot/GoPanel/rpc" "github.com/TicketsBot/GoPanel/rpc"
"github.com/TicketsBot/GoPanel/rpc/cache" "github.com/TicketsBot/GoPanel/rpc/cache"
"github.com/TicketsBot/GoPanel/rpc/ratelimit"
"github.com/TicketsBot/common/premium" "github.com/TicketsBot/common/premium"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/rxdn/gdl/rest" "github.com/rxdn/gdl/rest"
@ -22,6 +21,15 @@ func SendMessage(ctx *gin.Context) {
guildId := ctx.Keys["guildid"].(uint64) guildId := ctx.Keys["guildid"].(uint64)
userId := ctx.Keys["userid"].(uint64) userId := ctx.Keys["userid"].(uint64)
botContext, err := botcontext.ContextForGuild(guildId)
if err != nil {
ctx.AbortWithStatusJSON(500, gin.H{
"success": false,
"error": err.Error(),
})
return
}
// Get ticket ID // Get ticket ID
ticketId, err := strconv.Atoi(ctx.Param("ticketId")) ticketId, err := strconv.Atoi(ctx.Param("ticketId"))
if err != nil { if err != nil {
@ -42,8 +50,7 @@ func SendMessage(ctx *gin.Context) {
} }
// Verify guild is premium // Verify guild is premium
// TODO: Whitelabel tokens & ratelimiters premiumTier := rpc.PremiumClient.GetTierByGuildId(guildId, true, botContext.Token, botContext.RateLimiter)
premiumTier := rpc.PremiumClient.GetTierByGuildId(guildId, true, config.Conf.Bot.Token, ratelimit.Ratelimiter)
if premiumTier == premium.None { if premiumTier == premium.None {
ctx.AbortWithStatusJSON(402, gin.H{ ctx.AbortWithStatusJSON(402, gin.H{
"success": false, "success": false,
@ -90,8 +97,8 @@ func SendMessage(ctx *gin.Context) {
} }
if webhook.Id != 0 { if webhook.Id != 0 {
// TODO: Use gdl execute webhook wrapper // TODO: Ratelimit
_, err = rest.ExecuteWebhook(webhook.Token, ratelimit.Ratelimiter, webhook.Id, true, rest.WebhookBody{ _, err = rest.ExecuteWebhook(webhook.Token, nil, webhook.Id, true, rest.WebhookBody{
Content: body.Message, Content: body.Message,
Username: user.Username, Username: user.Username,
AvatarUrl: user.AvatarUrl(256), AvatarUrl: user.AvatarUrl(256),
@ -124,7 +131,7 @@ func SendMessage(ctx *gin.Context) {
return return
} }
if _, err = rest.CreateMessage(config.Conf.Bot.Token, ratelimit.Ratelimiter, *ticket.ChannelId, rest.CreateMessageData{Content: body.Message}); err != nil { if _, err = rest.CreateMessage(botContext.Token, botContext.RateLimiter, *ticket.ChannelId, rest.CreateMessageData{Content: body.Message}); err != nil {
ctx.AbortWithStatusJSON(500, gin.H{ ctx.AbortWithStatusJSON(500, gin.H{
"success": false, "success": false,
"error": err.Error(), "error": err.Error(),

View File

@ -8,6 +8,7 @@ import (
"github.com/TicketsBot/GoPanel/rpc/cache" "github.com/TicketsBot/GoPanel/rpc/cache"
"github.com/TicketsBot/GoPanel/utils" "github.com/TicketsBot/GoPanel/utils"
"github.com/TicketsBot/archiverclient" "github.com/TicketsBot/archiverclient"
"github.com/TicketsBot/common/permission"
"github.com/gin-gonic/contrib/sessions" "github.com/gin-gonic/contrib/sessions"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"strconv" "strconv"
@ -58,10 +59,7 @@ func LogViewHandler(ctx *gin.Context) {
} }
// Verify the user has permissions to be here // Verify the user has permissions to be here
// TODO: Allow support reps to view if utils.GetPermissionLevel(guildId, userId) < permission.Support && ticket.UserId != userId {
isAdmin := make(chan bool)
go utils.IsAdmin(guild, userId, isAdmin)
if !<-isAdmin && ticket.UserId != userId {
ctx.Redirect(302, config.Conf.Server.BaseUrl) // TODO: 403 Page ctx.Redirect(302, config.Conf.Server.BaseUrl) // TODO: 403 Page
return return
} }

View File

@ -8,6 +8,7 @@ import (
"github.com/TicketsBot/GoPanel/rpc/cache" "github.com/TicketsBot/GoPanel/rpc/cache"
"github.com/TicketsBot/GoPanel/utils" "github.com/TicketsBot/GoPanel/utils"
"github.com/TicketsBot/archiverclient" "github.com/TicketsBot/archiverclient"
"github.com/TicketsBot/common/permission"
"github.com/gin-gonic/contrib/sessions" "github.com/gin-gonic/contrib/sessions"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/gofrs/uuid" "github.com/gofrs/uuid"
@ -68,9 +69,7 @@ func ModmailLogViewHandler(ctx *gin.Context) {
} }
// Verify the user has permissions to be here // Verify the user has permissions to be here
isAdmin := make(chan bool) if utils.GetPermissionLevel(guildId, userId) < permission.Support && archive.UserId != userId {
go utils.IsAdmin(guild, userId, isAdmin)
if !<-isAdmin && archive.UserId != userId {
ctx.Redirect(302, config.Conf.Server.BaseUrl) // TODO: 403 Page ctx.Redirect(302, config.Conf.Server.BaseUrl) // TODO: 403 Page
return return
} }

View File

@ -2,11 +2,11 @@ package manage
import ( import (
"fmt" "fmt"
"github.com/TicketsBot/GoPanel/config" "github.com/TicketsBot/GoPanel/botcontext"
"github.com/TicketsBot/GoPanel/rpc" "github.com/TicketsBot/GoPanel/rpc"
"github.com/TicketsBot/GoPanel/rpc/cache" "github.com/TicketsBot/GoPanel/rpc/cache"
"github.com/TicketsBot/GoPanel/rpc/ratelimit"
"github.com/TicketsBot/GoPanel/utils" "github.com/TicketsBot/GoPanel/utils"
"github.com/TicketsBot/common/permission"
"github.com/TicketsBot/common/premium" "github.com/TicketsBot/common/premium"
"github.com/gin-gonic/contrib/sessions" "github.com/gin-gonic/contrib/sessions"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@ -117,17 +117,23 @@ func WebChatWs(ctx *gin.Context) {
guild, _ := cache.Instance.GetGuild(guildIdParsed, false) guild, _ := cache.Instance.GetGuild(guildIdParsed, false)
// Verify the user has permissions to be here // Verify the user has permissions to be here
isAdmin := make(chan bool) if utils.GetPermissionLevel(guild.Id, userId) < permission.Admin {
go utils.IsAdmin(guild, userId, isAdmin)
if !<-isAdmin {
fmt.Println(err.Error()) fmt.Println(err.Error())
conn.Close() conn.Close()
return return
} }
botContext, err := botcontext.ContextForGuild(guildIdParsed)
if err != nil {
ctx.AbortWithStatusJSON(500, gin.H{
"success": false,
"error": err.Error(),
})
return
}
// Verify the guild is premium // Verify the guild is premium
// TODO: Whitelabel tokens & ratelimiters premiumTier := rpc.PremiumClient.GetTierByGuildId(guildIdParsed, true, botContext.Token, botContext.RateLimiter)
premiumTier := rpc.PremiumClient.GetTierByGuildId(guildIdParsed, true, config.Conf.Bot.Token, ratelimit.Ratelimiter)
if premiumTier == premium.None { if premiumTier == premium.None {
conn.Close() conn.Close()
return return

View File

@ -5,6 +5,7 @@ import (
"github.com/TicketsBot/GoPanel/config" "github.com/TicketsBot/GoPanel/config"
"github.com/TicketsBot/GoPanel/rpc/cache" "github.com/TicketsBot/GoPanel/rpc/cache"
"github.com/TicketsBot/GoPanel/utils" "github.com/TicketsBot/GoPanel/utils"
"github.com/TicketsBot/common/permission"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"strconv" "strconv"
) )
@ -43,9 +44,8 @@ func AuthenticateGuild(isApiMethod bool) gin.HandlerFunc {
ctx.Keys["guild"] = guild ctx.Keys["guild"] = guild
// Verify the user has permissions to be here // Verify the user has permissions to be here
isAdmin := make(chan bool) userId := ctx.Keys["userid"].(uint64)
go utils.IsAdmin(guild, ctx.Keys["userid"].(uint64), isAdmin) if utils.GetPermissionLevel(guild.Id, userId) != permission.Admin {
if !<-isAdmin {
if isApiMethod { if isApiMethod {
ctx.AbortWithStatusJSON(403, gin.H{ ctx.AbortWithStatusJSON(403, gin.H{
"success": false, "success": false,

90
botcontext/botcontext.go Normal file
View File

@ -0,0 +1,90 @@
package botcontext
import (
"github.com/TicketsBot/GoPanel/config"
dbclient "github.com/TicketsBot/GoPanel/database"
"github.com/TicketsBot/GoPanel/messagequeue"
"github.com/TicketsBot/GoPanel/rpc/cache"
"github.com/TicketsBot/database"
"github.com/go-redis/redis"
"github.com/rxdn/gdl/objects/channel"
"github.com/rxdn/gdl/objects/guild"
"github.com/rxdn/gdl/objects/member"
"github.com/rxdn/gdl/rest"
"github.com/rxdn/gdl/rest/ratelimit"
)
type BotContext struct {
Token string
RateLimiter *ratelimit.Ratelimiter
}
func (ctx BotContext) Db() *database.Database {
return dbclient.Client
}
func (ctx BotContext) Redis() *redis.Client {
return messagequeue.Client.Client
}
func (ctx BotContext) IsBotAdmin(userId uint64) bool {
for _, id := range config.Conf.Admins {
if id == userId {
return true
}
}
return false
}
func (ctx BotContext) GetGuild(guildId uint64) (g guild.Guild, err error) {
if guild, found := cache.Instance.GetGuild(guildId, false); found {
return guild, nil
}
g, err = rest.GetGuild(ctx.Token, ctx.RateLimiter, guildId)
if err == nil {
go cache.Instance.StoreGuild(g)
}
return
}
func (ctx BotContext) GetChannel(channelId uint64) (ch channel.Channel, err error) {
if channel, found := cache.Instance.GetChannel(channelId); found {
return channel, nil
}
ch, err = rest.GetChannel(ctx.Token, ctx.RateLimiter, channelId)
if err == nil {
go cache.Instance.StoreChannel(ch)
}
return
}
func (ctx BotContext) GetGuildMember(guildId, userId uint64) (m member.Member, err error) {
if guild, found := cache.Instance.GetMember(guildId, userId); found {
return guild, nil
}
m, err = rest.GetGuildMember(ctx.Token, ctx.RateLimiter, guildId, userId)
if err == nil {
go cache.Instance.StoreMember(m, guildId)
}
return
}
func (ctx BotContext) GetGuildRoles(guildId uint64) (roles []guild.Role, err error) {
if roles := cache.Instance.GetGuildRoles(guildId); len(roles) > 0 {
return roles, nil
}
roles, err = rest.GetGuildRoles(ctx.Token, ctx.RateLimiter, guildId)
if err == nil {
go cache.Instance.StoreRoles(roles, guildId)
}
return
}

36
botcontext/get.go Normal file
View File

@ -0,0 +1,36 @@
package botcontext
import (
"fmt"
"github.com/TicketsBot/GoPanel/config"
dbclient "github.com/TicketsBot/GoPanel/database"
"github.com/TicketsBot/GoPanel/messagequeue"
"github.com/rxdn/gdl/rest/ratelimit"
)
func ContextForGuild(guildId uint64) (ctx BotContext, err error) {
whitelabelBotId, isWhitelabel, err := dbclient.Client.WhitelabelGuilds.GetBotByGuild(guildId)
if err != nil {
return
}
var keyPrefix string
if isWhitelabel {
res, err := dbclient.Client.Whitelabel.GetByBotId(whitelabelBotId)
if err != nil {
return ctx, err
}
ctx.Token = res.Token
keyPrefix = fmt.Sprintf("ratelimiter:%d", whitelabelBotId)
} else {
ctx.Token = config.Conf.Bot.Token
keyPrefix = "ratelimiter:public"
}
// TODO: Large sharding buckets
ctx.RateLimiter = ratelimit.NewRateLimiter(ratelimit.NewRedisStore(messagequeue.Client.Client, keyPrefix), 1)
return
}

View File

@ -11,12 +11,10 @@ import (
"github.com/TicketsBot/GoPanel/messagequeue" "github.com/TicketsBot/GoPanel/messagequeue"
"github.com/TicketsBot/GoPanel/rpc" "github.com/TicketsBot/GoPanel/rpc"
"github.com/TicketsBot/GoPanel/rpc/cache" "github.com/TicketsBot/GoPanel/rpc/cache"
"github.com/TicketsBot/GoPanel/rpc/ratelimit"
"github.com/TicketsBot/GoPanel/utils" "github.com/TicketsBot/GoPanel/utils"
"github.com/TicketsBot/archiverclient" "github.com/TicketsBot/archiverclient"
"github.com/TicketsBot/common/premium" "github.com/TicketsBot/common/premium"
"github.com/apex/log" "github.com/apex/log"
gdlratelimit "github.com/rxdn/gdl/rest/ratelimit"
"math/rand" "math/rand"
"time" "time"
) )
@ -49,8 +47,6 @@ func main() {
database.Client, database.Client,
) )
ratelimit.Ratelimiter = gdlratelimit.NewRateLimiter(gdlratelimit.NewRedisStore(messagequeue.Client.Client, "ratelimit"), 1) // TODO: Use values from config
http.StartServer() http.StartServer()
} }

View File

@ -1,4 +1,4 @@
admins=["217617036749176833"] admins=[585576154958921739]
[server] [server]
host="0.0.0.0:3000" host="0.0.0.0:3000"

View File

@ -7,7 +7,7 @@ import (
type ( type (
Config struct { Config struct {
Admins []string Admins []uint64
Server Server Server Server
Oauth Oauth Oauth Oauth
Database Database Database Database

4
go.mod
View File

@ -5,8 +5,8 @@ go 1.14
require ( require (
github.com/BurntSushi/toml v0.3.1 github.com/BurntSushi/toml v0.3.1
github.com/TicketsBot/archiverclient v0.0.0-20200425115930-0ca198cc8306 github.com/TicketsBot/archiverclient v0.0.0-20200425115930-0ca198cc8306
github.com/TicketsBot/common v0.0.0-20200526165242-b17694befe05 github.com/TicketsBot/common v0.0.0-20200527174950-d8ebbcbf49c9
github.com/TicketsBot/database v0.0.0-20200526163954-2cb21ac72d23 github.com/TicketsBot/database v0.0.0-20200527183847-2fbafde7649e
github.com/apex/log v1.1.2 github.com/apex/log v1.1.2
github.com/boj/redistore v0.0.0-20180917114910-cd5dcc76aeff // indirect github.com/boj/redistore v0.0.0-20180917114910-cd5dcc76aeff // indirect
github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/dgrijalva/jwt-go v3.2.0+incompatible

View File

@ -1,7 +0,0 @@
package ratelimit
import (
"github.com/rxdn/gdl/rest/ratelimit"
)
var Ratelimiter *ratelimit.Ratelimiter

View File

@ -1,133 +1,21 @@
package utils package utils
import ( import (
"context" "github.com/TicketsBot/GoPanel/botcontext"
"errors" "github.com/TicketsBot/common/permission"
"github.com/TicketsBot/GoPanel/config"
"github.com/TicketsBot/GoPanel/database"
"github.com/TicketsBot/GoPanel/rpc/cache"
"github.com/TicketsBot/GoPanel/rpc/ratelimit"
"github.com/apex/log"
"github.com/rxdn/gdl/objects/guild"
"github.com/rxdn/gdl/permission"
"github.com/rxdn/gdl/rest"
"golang.org/x/sync/errgroup"
"strconv"
"sync"
) )
// TODO: Use Redis cache func GetPermissionLevel(guildId, userId uint64) permission.PermissionLevel {
// TODO: Error handling botContext, err := botcontext.ContextForGuild(guildId)
func IsAdmin(g guild.Guild, userId uint64, res chan bool) {
if Contains(config.Conf.Admins, strconv.FormatUint(userId, 10)) {
res <- true
return
}
if g.OwnerId == userId {
res <- true
return
}
if isAdmin, _ := database.Client.Permissions.IsAdmin(g.Id, userId); isAdmin {
res <- true
return
}
userRoles, _ := getRoles(g.Id, userId)
// check if user has administrator permission
if hasAdministratorPermission(g.Id, userRoles) {
res <- true
return
}
adminRoles, _ := database.Client.RolePermissions.GetAdminRoles(g.Id)
hasTicketAdminRole := false
for _, userRole := range userRoles {
for _, adminRole := range adminRoles {
if userRole == adminRole {
hasTicketAdminRole = true
break
}
}
}
if hasTicketAdminRole {
res <- true
return
}
res <- false
}
func getRoles(guildId, userId uint64) ([]uint64, bool) {
member, found := cache.Instance.GetMember(guildId, userId)
if !found { // get from rest
var err error
member, err = rest.GetGuildMember(config.Conf.Bot.Token, ratelimit.Ratelimiter, guildId, userId)
if err != nil { if err != nil {
return nil, false return permission.Everyone
} }
// cache // get member
cache.Instance.StoreMember(member, guildId) member, err := botContext.GetGuildMember(guildId, userId)
}
return member.Roles, true
}
func hasAdministratorPermission(guildId uint64, roles []uint64) bool {
var lock sync.Mutex
var hasAdministrator bool
group, _ := errgroup.WithContext(context.Background())
for _, roleId := range roles {
group.Go(func() error {
roleHasAdmin, err := roleHasAdministrator(guildId, roleId)
if err != nil { if err != nil {
return err return permission.Everyone
} }
if roleHasAdmin { return permission.GetPermissionLevel(botContext, member, guildId)
lock.Lock()
hasAdministrator = true
lock.Unlock()
}
return nil
})
}
if err := group.Wait(); err != nil {
return false
}
return hasAdministrator
}
func roleHasAdministrator(guildId, roleId uint64) (bool, error) {
role, found := cache.Instance.GetRole(roleId)
if !found {
roles, err := rest.GetGuildRoles(config.Conf.Bot.Token, ratelimit.Ratelimiter, guildId)
if err != nil {
log.Error(err.Error())
return false, err
}
go cache.Instance.StoreRoles(roles, guildId)
for _, r := range roles {
if r.Id == roleId {
role = r
found = true
break
}
}
if !found {
return false, errors.New("role does not exist")
}
}
return permission.HasPermissionRaw(role.Permissions, permission.Administrator), nil
} }