2019-11-01 12:55:51 +00:00

280 lines
7.7 KiB
Go

package manage
import (
"encoding/base64"
"encoding/json"
"github.com/TicketsBot/GoPanel/app/http/template"
"github.com/TicketsBot/GoPanel/config"
"github.com/TicketsBot/GoPanel/database/table"
"github.com/TicketsBot/GoPanel/utils"
guildendpoint "github.com/TicketsBot/GoPanel/utils/discord/endpoints/guild"
"github.com/TicketsBot/GoPanel/utils/discord/objects"
"github.com/apex/log"
"github.com/gin-gonic/contrib/sessions"
"github.com/gin-gonic/gin"
"strconv"
)
func SettingsHandler(ctx *gin.Context) {
store := sessions.Default(ctx)
if store == nil {
return
}
defer store.Save()
if utils.IsLoggedIn(store) {
userIdStr := store.Get("userid").(string)
userId, err := utils.GetUserId(store)
if err != nil {
ctx.String(500, err.Error())
return
}
// Verify the guild exists
guildIdStr := ctx.Param("id")
guildId, err := strconv.ParseInt(guildIdStr, 10, 64)
if err != nil {
ctx.Redirect(302, config.Conf.Server.BaseUrl) // TODO: 404 Page
return
}
// Get object for selected guild
var guild objects.Guild
for _, g := range table.GetGuilds(userIdStr) {
if g.Id == guildIdStr {
guild = g
break
}
}
// Verify the user has permissions to be here
if !guild.Owner && !table.IsAdmin(guildId, userId) {
ctx.Redirect(302, config.Conf.Server.BaseUrl) // TODO: 403 Page
return
}
// Get CSRF token
csrfCorrect := ctx.Query("csrf") == store.Get("csrf").(string)
// Get prefix
prefix := ctx.Query("prefix")
if prefix == "" || len(prefix) > 8 || !csrfCorrect {
prefix = table.GetPrefix(guildId)
} else {
table.UpdatePrefix(guildId, prefix)
}
// Get welcome message
welcomeMessage := ctx.Query("welcomeMessage")
if welcomeMessage == "" || len(welcomeMessage) > 1000 || !csrfCorrect {
welcomeMessage = table.GetWelcomeMessage(guildId)
} else {
table.UpdateWelcomeMessage(guildId, welcomeMessage)
}
// Get ticket limit
limitStr := ctx.Query("ticketlimit")
limit := 5
// Verify input is an int and overwrite default limit
if utils.IsInt(limitStr) {
limit, _ = strconv.Atoi(limitStr)
}
// Update limit, or get current limit if user input is invalid
invalidTicketLimit := false
if limitStr == "" || !utils.IsInt(limitStr) || limit > 10 || limit < 1 || !csrfCorrect {
limit = table.GetTicketLimit(guildId)
if limitStr != "" { // User wasn't setting anything
invalidTicketLimit = true
}
} else {
table.UpdateTicketLimit(guildId, limit)
}
// Ping everyone
pingEveryone := table.GetPingEveryone(guildId)
pingEveryoneStr := ctx.Query("pingeveryone")
if csrfCorrect {
pingEveryone = pingEveryoneStr == "on"
table.UpdatePingEveryone(guildId, pingEveryone)
}
// /users/@me/guilds doesn't return channels, so we have to get them for the specific guild
if len(guild.Channels) == 0 {
var channels []objects.Channel
endpoint := guildendpoint.GetGuildChannels(int(guildId))
err = endpoint.Request(store, nil, nil, &channels)
if err != nil {
// Not in guild
} else {
guild.Channels = channels
// Update cache of categories now that we have them
guilds := table.GetGuilds(userIdStr)
// Get index of guild
index := -1
for i, g := range guilds {
if g.Id == guild.Id {
index = i
break
}
}
if index != -1 {
// Delete
guilds = append(guilds[:index], guilds[index+1:]...)
// Insert updated guild
guilds = utils.Insert(guilds, index, guild)
marshalled, err := json.Marshal(guilds)
if err != nil {
log.Error(err.Error())
} else {
if csrfCorrect {
table.UpdateGuilds(userIdStr, base64.StdEncoding.EncodeToString(marshalled))
}
}
}
}
}
// Get a list of actual category IDs
categories := guild.GetCategories()
// Convert to category IDs
var categoryIds []string
for _, c := range categories {
categoryIds = append(categoryIds, c.Id)
}
categoryStr := ctx.Query("category")
var category int64
// Verify category ID is an int and set default category ID
if utils.IsInt(categoryStr) {
category, _ = strconv.ParseInt(categoryStr, 10, 64)
}
// Update category, or get current category if user input is invalid
if categoryStr == "" || !utils.IsInt(categoryStr) || !utils.Contains(categoryIds, categoryStr) || !csrfCorrect {
category = table.GetChannelCategory(guildId)
} else {
table.UpdateChannelCategory(guildId, category)
}
var formattedCategories []map[string]interface{}
for _, c := range categories {
formattedCategories = append(formattedCategories, map[string]interface{}{
"categoryid": c.Id,
"categoryname": c.Name,
"active": c.Id == strconv.Itoa(int(category)),
})
}
// Archive channel
// Create a list of IDs
var channelIds []string
for _, c := range guild.Channels {
channelIds = append(channelIds, c.Id)
}
// Update or get current archive channel if blank or invalid
var archiveChannel int64
archiveChannelStr := ctx.Query("archivechannel")
// Verify category ID is an int and set default category ID
if utils.IsInt(archiveChannelStr) {
archiveChannel, _ = strconv.ParseInt(archiveChannelStr, 10, 64)
}
if archiveChannelStr == "" || !utils.IsInt(archiveChannelStr) || !utils.Contains(channelIds, archiveChannelStr) || !csrfCorrect {
archiveChannel = table.GetArchiveChannel(guildId)
} else {
table.UpdateArchiveChannel(guildId, archiveChannel)
}
// Format channels for templating
var formattedChannels []map[string]interface{}
for _, c := range guild.Channels {
if c.Type == 0 {
formattedChannels = append(formattedChannels, map[string]interface{}{
"channelid": c.Id,
"channelname": c.Name,
"active": c.Id == strconv.Itoa(int(archiveChannel)),
})
}
}
panelSettings := table.GetPanelSettings(guildId)
panelUpdated := false
// Get panel title
panelTitle := ctx.Query("paneltitle")
if panelTitle == "" || len(panelTitle) > 255 || !csrfCorrect {
panelTitle = panelSettings.Title
} else {
panelUpdated = true
}
// Get panel content
panelContent := ctx.Query("panelcontent")
if panelContent == "" || len(panelContent) > 2048 || !csrfCorrect {
panelContent = panelSettings.Content
} else {
panelUpdated = true
}
// Get panel colour
var panelColour uint64
panelColourHex := ctx.Query("panelcolour")
if panelColourHex == "" || !csrfCorrect {
panelColour = uint64(panelSettings.Colour)
} else {
panelUpdated = true
panelColour, err = strconv.ParseUint(panelColourHex, 16, 32)
}
if panelUpdated {
go table.UpdatePanelSettings(guildId, panelTitle, panelContent, int(panelColour))
}
// Users can close
usersCanCloseChan := make(chan bool)
go table.IsUserCanClose(guildId, usersCanCloseChan)
usersCanClose := <-usersCanCloseChan
usersCanCloseStr := ctx.Query("userscanclose")
if csrfCorrect {
usersCanClose = usersCanCloseStr == "on"
table.SetUserCanClose(guildId, usersCanClose)
}
utils.Respond(ctx, template.TemplateSettings.Render(map[string]interface{}{
"name": store.Get("name").(string),
"guildId": guildIdStr,
"avatar": store.Get("avatar").(string),
"prefix": prefix,
"welcomeMessage": welcomeMessage,
"ticketLimit": limit,
"categories": formattedCategories,
"channels": formattedChannels,
"invalidPrefix": len(ctx.Query("prefix")) > 8,
"invalidWelcomeMessage": len(ctx.Query("welcomeMessage")) > 1000,
"invalidTicketLimit": invalidTicketLimit,
"csrf": store.Get("csrf").(string),
"pingEveryone": pingEveryone,
"paneltitle": panelTitle,
"panelcontent": panelContent,
"panelcolour": strconv.FormatInt(int64(panelColour), 16),
"usersCanClose": usersCanClose,
}))
} else {
ctx.Redirect(302, "/login")
}
}