Whitelabel slash commands
This commit is contained in:
parent
a8d14bf971
commit
61621906c0
@ -1,10 +1,12 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/TicketsBot/GoPanel/utils"
|
"github.com/TicketsBot/GoPanel/utils"
|
||||||
"github.com/TicketsBot/common/permission"
|
"github.com/TicketsBot/common/permission"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"golang.org/x/sync/errgroup"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@ -21,10 +23,11 @@ func GetPermissionLevel(ctx *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Check whether the bot is in the guild to prevent us getting maliciously 429'd
|
// TODO: This is insanely inefficient
|
||||||
|
|
||||||
levels := make(map[string]permission.PermissionLevel)
|
levels := make(map[string]permission.PermissionLevel)
|
||||||
|
|
||||||
|
group, _ := errgroup.WithContext(context.Background())
|
||||||
for _, raw := range guilds {
|
for _, raw := range guilds {
|
||||||
guildId, err := strconv.ParseUint(raw, 10, 64)
|
guildId, err := strconv.ParseUint(raw, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -35,8 +38,16 @@ func GetPermissionLevel(ctx *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
level := utils.GetPermissionLevel(guildId, userId)
|
group.Go(func() error {
|
||||||
levels[strconv.FormatUint(guildId, 10)] = level
|
level, err := utils.GetPermissionLevel(guildId, userId)
|
||||||
|
levels[strconv.FormatUint(guildId, 10)] = level
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := group.Wait(); err != nil {
|
||||||
|
ctx.JSON(500, utils.ErrorToResponse(err))
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.JSON(200, gin.H{
|
ctx.JSON(200, gin.H{
|
||||||
|
@ -3,6 +3,7 @@ package api
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"github.com/TicketsBot/GoPanel/database"
|
"github.com/TicketsBot/GoPanel/database"
|
||||||
|
"github.com/TicketsBot/GoPanel/rpc/cache"
|
||||||
"github.com/TicketsBot/GoPanel/utils"
|
"github.com/TicketsBot/GoPanel/utils"
|
||||||
"github.com/TicketsBot/common/permission"
|
"github.com/TicketsBot/common/permission"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
@ -39,6 +40,12 @@ func GetGuilds(ctx *gin.Context) {
|
|||||||
g := g
|
g := g
|
||||||
|
|
||||||
group.Go(func() error {
|
group.Go(func() error {
|
||||||
|
// verify bot is in guild
|
||||||
|
_, ok := cache.Instance.GetGuild(g.GuildId, false)
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
fakeGuild := guild.Guild{
|
fakeGuild := guild.Guild{
|
||||||
Id: g.GuildId,
|
Id: g.GuildId,
|
||||||
Owner: g.Owner,
|
Owner: g.Owner,
|
||||||
@ -49,7 +56,12 @@ func GetGuilds(ctx *gin.Context) {
|
|||||||
fakeGuild.OwnerId = userId
|
fakeGuild.OwnerId = userId
|
||||||
}
|
}
|
||||||
|
|
||||||
if utils.GetPermissionLevel(g.GuildId, userId) >= permission.Support {
|
permLevel, err := utils.GetPermissionLevel(g.GuildId, userId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if permLevel >= permission.Support {
|
||||||
lock.Lock()
|
lock.Lock()
|
||||||
adminGuilds = append(adminGuilds, wrappedGuild{
|
adminGuilds = append(adminGuilds, wrappedGuild{
|
||||||
Id: g.GuildId,
|
Id: g.GuildId,
|
||||||
@ -58,6 +70,7 @@ func GetGuilds(ctx *gin.Context) {
|
|||||||
})
|
})
|
||||||
lock.Unlock()
|
lock.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,72 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/TicketsBot/GoPanel/botcontext"
|
||||||
|
"github.com/TicketsBot/GoPanel/database"
|
||||||
|
command "github.com/TicketsBot/worker/bot/command/impl"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/rxdn/gdl/rest"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func WhitelabelCreateInteractions(ctx *gin.Context) {
|
||||||
|
userId := ctx.Keys["userid"].(uint64)
|
||||||
|
|
||||||
|
// Get bot
|
||||||
|
bot, err := database.Client.Whitelabel.GetByUserId(userId)
|
||||||
|
if err != nil {
|
||||||
|
ctx.JSON(500, gin.H{
|
||||||
|
"success": false,
|
||||||
|
"error": err.Error(),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure bot exists
|
||||||
|
if bot.BotId == 0 {
|
||||||
|
ctx.JSON(404, gin.H{
|
||||||
|
"success": false,
|
||||||
|
"error": "No bot found",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
botContext, err := botcontext.ContextForGuild(0)
|
||||||
|
if err != nil {
|
||||||
|
ctx.JSON(500, gin.H{
|
||||||
|
"success": false,
|
||||||
|
"error": err.Error(),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, cmd := range command.Commands {
|
||||||
|
properties := cmd.Properties()
|
||||||
|
|
||||||
|
if properties.MessageOnly || properties.AdminOnly || properties.HelperOnly {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
option := command.BuildOption(cmd)
|
||||||
|
|
||||||
|
data := rest.CreateCommandData{
|
||||||
|
Name: option.Name,
|
||||||
|
Description: option.Description,
|
||||||
|
Options: option.Options,
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := rest.CreateGlobalCommand(bot.Token, botContext.RateLimiter, bot.BotId, data); err != nil {
|
||||||
|
ctx.JSON(500, gin.H{
|
||||||
|
"success": false,
|
||||||
|
"error": err.Error(),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.JSON(200, gin.H{
|
||||||
|
"success": true,
|
||||||
|
})
|
||||||
|
}
|
53
app/http/endpoints/api/whitelabel/whitelabelgetpublickey.go
Normal file
53
app/http/endpoints/api/whitelabel/whitelabelgetpublickey.go
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/TicketsBot/GoPanel/database"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func WhitelabelGetPublicKey(ctx *gin.Context) {
|
||||||
|
type data struct {
|
||||||
|
PublicKey string `json:"public_key"`
|
||||||
|
}
|
||||||
|
|
||||||
|
userId := ctx.Keys["userid"].(uint64)
|
||||||
|
|
||||||
|
// Get bot
|
||||||
|
bot, err := database.Client.Whitelabel.GetByUserId(userId)
|
||||||
|
if err != nil {
|
||||||
|
ctx.JSON(500, gin.H{
|
||||||
|
"success": false,
|
||||||
|
"error": err.Error(),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure bot exists
|
||||||
|
if bot.BotId == 0 {
|
||||||
|
ctx.JSON(404, gin.H{
|
||||||
|
"success": false,
|
||||||
|
"error": "No bot found",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
key, err := database.Client.WhitelabelKeys.Get(bot.BotId)
|
||||||
|
if err != nil {
|
||||||
|
ctx.JSON(500, gin.H{
|
||||||
|
"success": false,
|
||||||
|
"error": err.Error(),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if key == "" {
|
||||||
|
ctx.JSON(404, gin.H{
|
||||||
|
"success": false,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
ctx.JSON(200, gin.H{
|
||||||
|
"success": true,
|
||||||
|
"key": key,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
65
app/http/endpoints/api/whitelabel/whitelabelpostpublickey.go
Normal file
65
app/http/endpoints/api/whitelabel/whitelabelpostpublickey.go
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/hex"
|
||||||
|
"github.com/TicketsBot/GoPanel/database"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func WhitelabelPostPublicKey(ctx *gin.Context) {
|
||||||
|
type data struct {
|
||||||
|
PublicKey string `json:"public_key"`
|
||||||
|
}
|
||||||
|
|
||||||
|
userId := ctx.Keys["userid"].(uint64)
|
||||||
|
|
||||||
|
// Get bot
|
||||||
|
bot, err := database.Client.Whitelabel.GetByUserId(userId)
|
||||||
|
if err != nil {
|
||||||
|
ctx.JSON(500, gin.H{
|
||||||
|
"success": false,
|
||||||
|
"error": err.Error(),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure bot exists
|
||||||
|
if bot.BotId == 0 {
|
||||||
|
ctx.JSON(404, gin.H{
|
||||||
|
"success": false,
|
||||||
|
"error": "No bot found",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse status
|
||||||
|
var body data
|
||||||
|
if err := ctx.BindJSON(&body); err != nil {
|
||||||
|
ctx.JSON(400, gin.H{
|
||||||
|
"success": false,
|
||||||
|
"error": "No public key provided",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes, err := hex.DecodeString(body.PublicKey)
|
||||||
|
if err != nil || len(bytes) != 32 {
|
||||||
|
ctx.JSON(400, gin.H{
|
||||||
|
"success": false,
|
||||||
|
"error": "Invalid public key",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := database.Client.WhitelabelKeys.Set(bot.BotId, body.PublicKey); err != nil {
|
||||||
|
ctx.JSON(500, gin.H{
|
||||||
|
"success": false,
|
||||||
|
"error": err.Error(),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.JSON(200, gin.H{
|
||||||
|
"success": true,
|
||||||
|
})
|
||||||
|
}
|
@ -59,7 +59,13 @@ func LogViewHandler(ctx *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Verify the user has permissions to be here
|
// Verify the user has permissions to be here
|
||||||
if utils.GetPermissionLevel(guildId, userId) < permission.Support && ticket.UserId != userId {
|
permLevel, err := utils.GetPermissionLevel(guildId, userId)
|
||||||
|
if err != nil {
|
||||||
|
ctx.JSON(500, utils.ErrorToResponse(err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if permLevel < permission.Support && 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
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,13 @@ func ModmailLogViewHandler(ctx *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Verify the user has permissions to be here
|
// Verify the user has permissions to be here
|
||||||
if utils.GetPermissionLevel(guildId, userId) < permission.Support && archive.UserId != userId {
|
permLevel, err := utils.GetPermissionLevel(guildId, userId)
|
||||||
|
if err != nil {
|
||||||
|
ctx.JSON(500, utils.ErrorToResponse(err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if permLevel < permission.Support && archive.UserId != userId {
|
||||||
utils.ErrorPage(ctx, 403, "You do not have permission to view this archive")
|
utils.ErrorPage(ctx, 403, "You do not have permission to view this archive")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"github.com/TicketsBot/GoPanel/botcontext"
|
"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/utils"
|
"github.com/TicketsBot/GoPanel/utils"
|
||||||
"github.com/TicketsBot/common/permission"
|
"github.com/TicketsBot/common/permission"
|
||||||
"github.com/TicketsBot/common/premium"
|
"github.com/TicketsBot/common/premium"
|
||||||
@ -113,11 +112,15 @@ func WebChatWs(ctx *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get object for selected guild
|
|
||||||
guild, _ := cache.Instance.GetGuild(guildIdParsed, false)
|
|
||||||
|
|
||||||
// Verify the user has permissions to be here
|
// Verify the user has permissions to be here
|
||||||
if utils.GetPermissionLevel(guild.Id, userId) < permission.Admin {
|
permLevel, err := utils.GetPermissionLevel(guildIdParsed, userId)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
conn.Close()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if permLevel < permission.Admin {
|
||||||
fmt.Println(err.Error())
|
fmt.Println(err.Error())
|
||||||
conn.Close()
|
conn.Close()
|
||||||
return
|
return
|
||||||
|
@ -46,7 +46,14 @@ func AuthenticateGuild(isApiMethod bool, requiredPermissionLevel permission.Perm
|
|||||||
|
|
||||||
// Verify the user has permissions to be here
|
// Verify the user has permissions to be here
|
||||||
userId := ctx.Keys["userid"].(uint64)
|
userId := ctx.Keys["userid"].(uint64)
|
||||||
if utils.GetPermissionLevel(guild.Id, userId) < requiredPermissionLevel {
|
|
||||||
|
permLevel, err := utils.GetPermissionLevel(guild.Id, userId)
|
||||||
|
if err != nil {
|
||||||
|
ctx.JSON(500, utils.ErrorToResponse(err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if permLevel < requiredPermissionLevel {
|
||||||
if isApiMethod {
|
if isApiMethod {
|
||||||
ctx.AbortWithStatusJSON(403, gin.H{
|
ctx.AbortWithStatusJSON(403, gin.H{
|
||||||
"success": false,
|
"success": false,
|
||||||
|
@ -47,7 +47,7 @@ func StartServer() {
|
|||||||
router.Use(static.Serve("/assets/", static.LocalFile("./public/static", false)))
|
router.Use(static.Serve("/assets/", static.LocalFile("./public/static", false)))
|
||||||
|
|
||||||
router.Use(gin.Recovery())
|
router.Use(gin.Recovery())
|
||||||
router.Use(createLimiter(600, time.Minute * 10))
|
router.Use(createLimiter(600, time.Minute*10))
|
||||||
|
|
||||||
// Register templates
|
// Register templates
|
||||||
router.HTMLRender = createRenderer()
|
router.HTMLRender = createRenderer()
|
||||||
@ -55,8 +55,7 @@ func StartServer() {
|
|||||||
router.GET("/login", root.LoginHandler)
|
router.GET("/login", root.LoginHandler)
|
||||||
router.GET("/callback", root.CallbackHandler)
|
router.GET("/callback", root.CallbackHandler)
|
||||||
|
|
||||||
router.GET("/manage/:id/logs/view/:ticket", manage.LogViewHandler) // we check in the actual handler bc of a custom redirect
|
router.GET("/manage/:id/logs/view/:ticket", manage.LogViewHandler) // we check in the actual handler bc of a custom redirect
|
||||||
router.GET("/manage/:id/logs/modmail/view/:uuid", manage.ModmailLogViewHandler) // we check in the actual handler bc of a custom redirect
|
|
||||||
|
|
||||||
authorized := router.Group("/", middleware.AuthenticateCookie)
|
authorized := router.Group("/", middleware.AuthenticateCookie)
|
||||||
{
|
{
|
||||||
@ -71,7 +70,6 @@ func StartServer() {
|
|||||||
|
|
||||||
authenticateGuildAdmin.GET("/manage/:id/settings", manage.SettingsHandler)
|
authenticateGuildAdmin.GET("/manage/:id/settings", manage.SettingsHandler)
|
||||||
authenticateGuildSupport.GET("/manage/:id/logs", manage.LogsHandler)
|
authenticateGuildSupport.GET("/manage/:id/logs", manage.LogsHandler)
|
||||||
authenticateGuildSupport.GET("/manage/:id/logs/modmail", manage.ModmailLogsHandler)
|
|
||||||
authenticateGuildSupport.GET("/manage/:id/blacklist", manage.BlacklistHandler)
|
authenticateGuildSupport.GET("/manage/:id/blacklist", manage.BlacklistHandler)
|
||||||
authenticateGuildAdmin.GET("/manage/:id/panels", manage.PanelHandler)
|
authenticateGuildAdmin.GET("/manage/:id/panels", manage.PanelHandler)
|
||||||
authenticateGuildSupport.GET("/manage/:id/tags", manage.TagsHandler)
|
authenticateGuildSupport.GET("/manage/:id/tags", manage.TagsHandler)
|
||||||
@ -139,10 +137,12 @@ func StartServer() {
|
|||||||
whitelabelGroup.GET("/", api_whitelabel.WhitelabelGet)
|
whitelabelGroup.GET("/", api_whitelabel.WhitelabelGet)
|
||||||
whitelabelApiGroup.GET("/errors", api_whitelabel.WhitelabelGetErrors)
|
whitelabelApiGroup.GET("/errors", api_whitelabel.WhitelabelGetErrors)
|
||||||
whitelabelApiGroup.GET("/guilds", api_whitelabel.WhitelabelGetGuilds)
|
whitelabelApiGroup.GET("/guilds", api_whitelabel.WhitelabelGetGuilds)
|
||||||
whitelabelApiGroup.POST("/modmail", api_whitelabel.WhitelabelModmailPost)
|
whitelabelApiGroup.GET("/public-key", api_whitelabel.WhitelabelGetPublicKey)
|
||||||
|
whitelabelApiGroup.POST("/public-key", api_whitelabel.WhitelabelPostPublicKey)
|
||||||
|
whitelabelApiGroup.POST("/create-interactions", api_whitelabel.WhitelabelCreateInteractions)
|
||||||
|
|
||||||
whitelabelApiGroup.Group("/").Use(createLimiter(10, time.Minute)).POST("/", api_whitelabel.WhitelabelPost)
|
whitelabelApiGroup.Group("/").Use(createLimiter(10, time.Minute)).POST("/", api_whitelabel.WhitelabelPost)
|
||||||
whitelabelApiGroup.Group("/").Use(createLimiter(1, time.Second * 5)).POST("/status", api_whitelabel.WhitelabelStatusPost)
|
whitelabelApiGroup.Group("/").Use(createLimiter(1, time.Second*5)).POST("/status", api_whitelabel.WhitelabelStatusPost)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,6 +177,7 @@ func addMainTemplate(renderer multitemplate.Renderer, name string, extra ...stri
|
|||||||
"./public/templates/includes/head.tmpl",
|
"./public/templates/includes/head.tmpl",
|
||||||
"./public/templates/includes/sidebar.tmpl",
|
"./public/templates/includes/sidebar.tmpl",
|
||||||
"./public/templates/includes/loadingscreen.tmpl",
|
"./public/templates/includes/loadingscreen.tmpl",
|
||||||
|
"./public/templates/includes/notifymodal.tmpl",
|
||||||
fmt.Sprintf("./public/templates/views/%s.tmpl", name),
|
fmt.Sprintf("./public/templates/views/%s.tmpl", name),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,8 +5,8 @@ import (
|
|||||||
dbclient "github.com/TicketsBot/GoPanel/database"
|
dbclient "github.com/TicketsBot/GoPanel/database"
|
||||||
"github.com/TicketsBot/GoPanel/messagequeue"
|
"github.com/TicketsBot/GoPanel/messagequeue"
|
||||||
"github.com/TicketsBot/GoPanel/rpc/cache"
|
"github.com/TicketsBot/GoPanel/rpc/cache"
|
||||||
|
"github.com/TicketsBot/common/permission"
|
||||||
"github.com/TicketsBot/database"
|
"github.com/TicketsBot/database"
|
||||||
"github.com/go-redis/redis"
|
|
||||||
"github.com/rxdn/gdl/objects/channel"
|
"github.com/rxdn/gdl/objects/channel"
|
||||||
"github.com/rxdn/gdl/objects/guild"
|
"github.com/rxdn/gdl/objects/guild"
|
||||||
"github.com/rxdn/gdl/objects/member"
|
"github.com/rxdn/gdl/objects/member"
|
||||||
@ -23,8 +23,8 @@ func (ctx BotContext) Db() *database.Database {
|
|||||||
return dbclient.Client
|
return dbclient.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx BotContext) Redis() *redis.Client {
|
func (ctx BotContext) Cache() permission.PermissionCache {
|
||||||
return messagequeue.Client.Client
|
return permission.NewRedisCache(messagequeue.Client.Client)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx BotContext) IsBotAdmin(userId uint64) bool {
|
func (ctx BotContext) IsBotAdmin(userId uint64) bool {
|
||||||
|
11
go.mod
11
go.mod
@ -5,9 +5,9 @@ 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-20200704164621-09d42dd941e0
|
github.com/TicketsBot/archiverclient v0.0.0-20200704164621-09d42dd941e0
|
||||||
github.com/TicketsBot/common v0.0.0-20200925115036-a1bbe85f45bb
|
github.com/TicketsBot/common v0.0.0-20201222195753-3dd751ebabf8
|
||||||
github.com/TicketsBot/database v0.0.0-20200723134637-72f4cd31eef6
|
github.com/TicketsBot/database v0.0.0-20201224193659-c89391f44b57
|
||||||
github.com/TicketsBot/logarchiver v0.0.0-20200425163447-199b93429026 // indirect
|
github.com/TicketsBot/worker v0.0.0-20201224203453-0c8f9a415306
|
||||||
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
|
||||||
@ -19,11 +19,10 @@ require (
|
|||||||
github.com/gofrs/uuid v3.3.0+incompatible
|
github.com/gofrs/uuid v3.3.0+incompatible
|
||||||
github.com/gorilla/sessions v1.2.0 // indirect
|
github.com/gorilla/sessions v1.2.0 // indirect
|
||||||
github.com/gorilla/websocket v1.4.2
|
github.com/gorilla/websocket v1.4.2
|
||||||
github.com/jackc/pgx/v4 v4.6.0
|
github.com/jackc/pgx/v4 v4.7.1
|
||||||
github.com/klauspost/compress v1.10.10 // indirect
|
|
||||||
github.com/pasztorpisti/qs v0.0.0-20171216220353-8d6c33ee906c
|
github.com/pasztorpisti/qs v0.0.0-20171216220353-8d6c33ee906c
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/rxdn/gdl v0.0.0-20201123164345-0469e0a3cea3
|
github.com/rxdn/gdl v0.0.0-20201214225805-4ae598a98327
|
||||||
github.com/sirupsen/logrus v1.5.0
|
github.com/sirupsen/logrus v1.5.0
|
||||||
github.com/ulule/limiter/v3 v3.5.0
|
github.com/ulule/limiter/v3 v3.5.0
|
||||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a
|
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a
|
||||||
|
@ -5,10 +5,7 @@
|
|||||||
<a class="nav-link" href="/manage/{{.guildId}}/settings"><i class="fas fa-cogs icon"></i>Settings</a>
|
<a class="nav-link" href="/manage/{{.guildId}}/settings"><i class="fas fa-cogs icon"></i>Settings</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="/manage/{{.guildId}}/logs"><i class="fas fa-copy icon"></i>Logs</a>
|
<a class="nav-link" href="/manage/{{.guildId}}/logs"><i class="fas fa-copy icon"></i>Transcripts</a>
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" href="/manage/{{.guildId}}/logs/modmail"><i class="fas fa-copy icon"></i>Modmail Logs</a>
|
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="/manage/{{.guildId}}/blacklist"><i class="fas fa-ban icon"></i>Blacklist</a>
|
<a class="nav-link" href="/manage/{{.guildId}}/blacklist"><i class="fas fa-ban icon"></i>Blacklist</a>
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
{{template "sidebar" .}}
|
{{template "sidebar" .}}
|
||||||
<div class="main-panel">
|
<div class="main-panel">
|
||||||
{{template "loadingscreen" .}}
|
{{template "loadingscreen" .}}
|
||||||
|
<script src="/assets/js/modalbackdrop.js"></script>
|
||||||
|
{{template "notifymodal" .}}
|
||||||
{{template "content" .}}
|
{{template "content" .}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Bot Token</label>
|
<label>Bot Token</label>
|
||||||
<input name="token" type="text" class="form-control"
|
<input name="token" type="text" class="form-control"
|
||||||
placeholder="9ViiGeUZlFJKIfSzodnzZT6W.bX8IAh.p9gG0tElMXg1EqwAChqaYz3swFY" id="token">
|
placeholder="xxxxxxxxxxxxxxxxxxxxxxxx.xxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxx" id="token">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -49,32 +49,40 @@
|
|||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<h4 class="card-title">Modmail</h4>
|
<h4 class="card-title">Slash Commands</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body" id="card">
|
<div class="card-body" id="card">
|
||||||
<form onsubmit="updateForcedModmail(); return false;">
|
<div class="container-fluid">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<div class="form-group">
|
<form onsubmit="updatePublicKey(); return false;">
|
||||||
<label>Server</label>
|
<div class="row">
|
||||||
<select class="form-control" id="forced_modmail">
|
<div class="col-md-9">
|
||||||
<option value="0">Allow user to select</option>
|
<div class="form-group">
|
||||||
</select>
|
<input name="public-key" type="text" class="form-control" placeholder="Public Key" id="public-key">
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<div class="form-group">
|
||||||
|
<button class="btn btn-primary btn-fill" type="submit">
|
||||||
|
<i class="fas fa-paper-plane"></i>
|
||||||
|
Submit
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-3">
|
<div class="col-md-12">
|
||||||
<div class="form-group">
|
<button class="btn btn-primary btn-fill" style="width: 100%" onclick="createSlashCommands()">
|
||||||
<button class="btn btn-primary btn-fill" type="submit">
|
<i class="fas fa-paper-plane"></i>
|
||||||
<i class="fas fa-paper-plane"></i>
|
Create Slash Commands
|
||||||
Submit
|
</button>
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -142,137 +150,133 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// invite button
|
// invite button
|
||||||
document.getElementById('invite').addEventListener('click', async () => {
|
document.getElementById('invite').addEventListener('click', async () => {
|
||||||
// get bot ID
|
// get bot ID
|
||||||
const res = await axios.get('/user/whitelabel');
|
const res = await axios.get('/user/whitelabel');
|
||||||
if (res.status !== 200 || !res.data.success) {
|
if (res.status !== 200 || !res.data.success) {
|
||||||
showToast('Error', res.data.error);
|
notifyError(res.data.error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const inviteUrl = 'https://discord.com/oauth2/authorize?client_id=' + res.data.id + '&scope=bot&permissions=805825648';
|
const inviteUrl = 'https://discord.com/oauth2/authorize?client_id=' + res.data.id + '&scope=bot&permissions=805825648';
|
||||||
|
|
||||||
window.open(inviteUrl, '_blank');
|
window.open(inviteUrl, '_blank');
|
||||||
}, false);
|
}, false);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
async function updateSettings() {
|
async function updateSettings() {
|
||||||
const data = {
|
const data = {
|
||||||
token: document.getElementById('token').value
|
token: document.getElementById('token').value
|
||||||
};
|
};
|
||||||
|
|
||||||
const res = await axios.post('/user/whitelabel', data);
|
const res = await axios.post('/user/whitelabel', data);
|
||||||
if (res.status !== 200 || !res.data.success) {
|
if (res.status !== 200 || !res.data.success) {
|
||||||
showToast('Error', res.data.error);
|
notifyError(res.data.error);
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
showToast('Success', `Started tickets whitelabel on ${res.data.bot.username}#${res.data.bot.discriminator}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updateForcedModmail() {
|
notifySuccess(`Started tickets whitelabel on ${res.data.bot.username}#${res.data.bot.discriminator}`);
|
||||||
const select = document.getElementById('forced_modmail');
|
}
|
||||||
const data = {
|
|
||||||
guild: select.options[select.selectedIndex].value
|
|
||||||
};
|
|
||||||
|
|
||||||
const res = await axios.post('/user/whitelabel/modmail', data);
|
async function updatePublicKey() {
|
||||||
if (res.status !== 200 || !res.data.success) {
|
const data = {
|
||||||
showToast('Error', res.data.error);
|
public_key: document.getElementById('public-key').value,
|
||||||
return;
|
};
|
||||||
}
|
|
||||||
|
|
||||||
showToast('Success', 'Updated modmail settings successfully')
|
const res = await axios.post('/user/whitelabel/public-key', data);
|
||||||
|
if (res.status !== 200 || !res.data.success) {
|
||||||
|
notifyError(res.data.error);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updateStatus() {
|
notifySuccess('Updated slash command settings successfully')
|
||||||
const data = {
|
}
|
||||||
status: document.getElementById('status').value
|
|
||||||
};
|
|
||||||
|
|
||||||
const res = await axios.post('/user/whitelabel/status', data);
|
async function updateStatus() {
|
||||||
if (res.status !== 200 || !res.data.success) {
|
const data = {
|
||||||
showToast('Error', res.data.error);
|
status: document.getElementById('status').value
|
||||||
return;
|
};
|
||||||
}
|
|
||||||
|
|
||||||
showToast('Success', 'Updated status successfully')
|
const res = await axios.post('/user/whitelabel/status', data);
|
||||||
|
if (res.status !== 200 || !res.data.success) {
|
||||||
|
notifyError(res.data.error);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadStatus() {
|
notifySuccess('Updated status successfully')
|
||||||
const res = await axios.get('/user/whitelabel');
|
}
|
||||||
if (res.status !== 200 || !res.data.success) {
|
|
||||||
if (res.status !== 404) {
|
|
||||||
showToast('Error', res.data.error);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set status
|
async function loadStatus() {
|
||||||
document.getElementById('status').value = res.data.status;
|
const res = await axios.get('/user/whitelabel');
|
||||||
|
if (res.status !== 200 || !res.data.success) {
|
||||||
|
if (res.status !== 404) {
|
||||||
|
notifyError(res.data.error);
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadErrors() {
|
// set status
|
||||||
const res = await axios.get('/user/whitelabel/errors');
|
document.getElementById('status').value = res.data.status;
|
||||||
if (res.status !== 200 || !res.data.success) {
|
}
|
||||||
showToast('Error', res.data.error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// append errors
|
async function loadErrors() {
|
||||||
if (res.data.errors !== null) {
|
const res = await axios.get('/user/whitelabel/errors');
|
||||||
for (error of res.data.errors) {
|
if (res.status !== 200 || !res.data.success) {
|
||||||
const message = error.Message;
|
notifyError(res.data.error);
|
||||||
const time = new Date(error.Time);
|
return;
|
||||||
|
|
||||||
const tr = document.createElement('tr');
|
|
||||||
appendTd(tr, message);
|
|
||||||
appendTd(tr, time.toDateString());
|
|
||||||
document.getElementById('error_body').appendChild(tr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadGuilds() {
|
// append errors
|
||||||
// get selected guild
|
if (res.data.errors !== null) {
|
||||||
const settingsRes = await axios.get('/user/whitelabel');
|
for (error of res.data.errors) {
|
||||||
if (settingsRes.status !== 200 || !settingsRes.data.success) {
|
const message = error.Message;
|
||||||
showToast('Error', settingsRes.data.error);
|
const time = new Date(error.Time);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const guildId = settingsRes.data.modmail_forced_guild;
|
const tr = document.createElement('tr');
|
||||||
|
appendTd(tr, message);
|
||||||
|
appendTd(tr, time.toDateString());
|
||||||
|
document.getElementById('error_body').appendChild(tr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// get guild list
|
async function loadPublicKey() {
|
||||||
const guildsRes = await axios.get('/user/whitelabel/guilds');
|
const res = await axios.get('/user/whitelabel/public-key');
|
||||||
if (guildsRes.status !== 200 || !guildsRes.data.success) {
|
if (res.status === 404) {
|
||||||
if (guildsRes.status !== 404) {
|
return;
|
||||||
showToast('Error', guildsRes.data.error);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// append guilds to dropdown
|
|
||||||
const select = document.getElementById('forced_modmail');
|
|
||||||
for (let [id, name] of Object.entries(guildsRes.data.guilds)) {
|
|
||||||
const option = document.createElement('option');
|
|
||||||
option.value = id;
|
|
||||||
option.text = name;
|
|
||||||
|
|
||||||
if (id === guildId) {
|
|
||||||
option.selected = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
select.add(option);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
withLoadingScreen(async () => {
|
if ((res.status !== 200 || !res.data.success)) {
|
||||||
await loadStatus();
|
notifyError(res.data.error);
|
||||||
await loadErrors();
|
return;
|
||||||
await loadGuilds();
|
}
|
||||||
});
|
|
||||||
|
const key = res.data.key;
|
||||||
|
document.getElementById('public-key').value = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createSlashCommands() {
|
||||||
|
notify('Slash Commands', 'Creating slash commands, please note this may take up to 120 seconds to complete');
|
||||||
|
|
||||||
|
const opts = {
|
||||||
|
timeout: 120 * 1000
|
||||||
|
};
|
||||||
|
|
||||||
|
const res = await axios.post('/user/whitelabel/create-interactions', {}, opts);
|
||||||
|
if (res.status !== 200 || !res.data.success) {
|
||||||
|
notifyError(res.data.error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
notifySuccess('Slash commands have been created. Please note, Discord may take up to an hour to show them in your client');
|
||||||
|
}
|
||||||
|
|
||||||
|
withLoadingScreen(async () => {
|
||||||
|
await loadStatus();
|
||||||
|
await loadErrors();
|
||||||
|
await loadPublicKey();
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
{{end}}
|
{{end}}
|
@ -5,20 +5,15 @@ import (
|
|||||||
"github.com/TicketsBot/common/permission"
|
"github.com/TicketsBot/common/permission"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetPermissionLevel(guildId, userId uint64) permission.PermissionLevel {
|
func GetPermissionLevel(guildId, userId uint64) (permission.PermissionLevel, error) {
|
||||||
botContext, err := botcontext.ContextForGuild(guildId)
|
botContext, err := botcontext.ContextForGuild(guildId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return permission.Everyone
|
return permission.Everyone, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if botContext.IsBotAdmin(userId) {
|
|
||||||
return permission.Admin
|
|
||||||
}
|
|
||||||
|
|
||||||
// get member
|
// get member
|
||||||
member, err := botContext.GetGuildMember(guildId, userId)
|
member, err := botContext.GetGuildMember(guildId, userId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return permission.Everyone
|
return permission.Everyone, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return permission.GetPermissionLevel(botContext, member, guildId)
|
return permission.GetPermissionLevel(botContext, member, guildId)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user