somewhat make this better

This commit is contained in:
Dot-Rar 2020-02-08 21:50:59 +00:00
parent 7aba0cc253
commit ddff17147c
7 changed files with 265 additions and 206 deletions

View File

@ -1,14 +1,10 @@
package manage package manage
import ( import (
"encoding/base64"
"encoding/json"
"github.com/TicketsBot/GoPanel/config" "github.com/TicketsBot/GoPanel/config"
"github.com/TicketsBot/GoPanel/database/table" "github.com/TicketsBot/GoPanel/database/table"
"github.com/TicketsBot/GoPanel/utils" "github.com/TicketsBot/GoPanel/utils"
guildendpoint "github.com/TicketsBot/GoPanel/utils/discord/endpoints/guild"
"github.com/TicketsBot/GoPanel/utils/discord/objects" "github.com/TicketsBot/GoPanel/utils/discord/objects"
"github.com/apex/log"
"github.com/gin-gonic/contrib/sessions" "github.com/gin-gonic/contrib/sessions"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"strconv" "strconv"
@ -52,128 +48,23 @@ func SettingsHandler(ctx *gin.Context) {
return return
} }
// Get CSRF token // Get settings from database
csrfCorrect := ctx.Query("csrf") == store.Get("csrf").(string) prefix := table.GetPrefix(guildId)
welcomeMessage := table.GetWelcomeMessage(guildId)
// Get prefix limit := table.GetTicketLimit(guildId)
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) pingEveryone := table.GetPingEveryone(guildId)
pingEveryoneStr := ctx.Query("pingeveryone") archiveChannel := table.GetArchiveChannel(guildId)
if csrfCorrect { categoryId := table.GetChannelCategory(guildId)
pingEveryone = pingEveryoneStr == "on"
table.UpdatePingEveryone(guildId, pingEveryone)
}
// /users/@me/guilds doesn't return channels, so we have to get them for the specific guild // /users/@me/guilds doesn't return channels, so we have to get them for the specific guild
if len(guild.Channels) == 0 { channelsChan := make(chan []table.Channel)
var channels []objects.Channel go table.GetCachedChannelsByGuild(guildId, channelsChan)
endpoint := guildendpoint.GetGuildChannels(int(guildId)) channels := <-channelsChan
err = endpoint.Request(store, nil, nil, &channels, nil)
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 // Get a list of actual category IDs
categories := guild.GetCategories() categoriesChan := make(chan []table.Channel)
go table.GetCategories(guildId, categoriesChan)
// Convert to category IDs categories := <-categoriesChan
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 // Archive channel
// Create a list of IDs // Create a list of IDs
@ -182,76 +73,16 @@ func SettingsHandler(ctx *gin.Context) {
channelIds = append(channelIds, c.Id) 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) 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 // Users can close
usersCanCloseChan := make(chan bool) usersCanCloseChan := make(chan bool)
go table.IsUserCanClose(guildId, usersCanCloseChan) go table.IsUserCanClose(guildId, usersCanCloseChan)
usersCanClose := <-usersCanCloseChan usersCanClose := <-usersCanCloseChan
usersCanCloseStr := ctx.Query("userscanclose") invalidPrefix := ctx.Query("validPrefix") == "false"
if csrfCorrect { invalidWelcomeMessage := ctx.Query("validWelcomeMessage") == "false"
usersCanClose = usersCanCloseStr == "on" invalidTicketLimit := ctx.Query("validTicketLimit") == "false"
table.SetUserCanClose(guildId, usersCanClose)
}
ctx.HTML(200, "manage/settings", gin.H{ ctx.HTML(200, "manage/settings", gin.H{
"name": store.Get("name").(string), "name": store.Get("name").(string),
@ -260,16 +91,18 @@ func SettingsHandler(ctx *gin.Context) {
"prefix": prefix, "prefix": prefix,
"welcomeMessage": welcomeMessage, "welcomeMessage": welcomeMessage,
"ticketLimit": limit, "ticketLimit": limit,
"categories": formattedCategories, "categories": categories,
"channels": formattedChannels, "activecategory": categoryId,
"invalidPrefix": len(ctx.Query("prefix")) > 8, "channels": channels,
"invalidWelcomeMessage": len(ctx.Query("welcomeMessage")) > 1000, "archivechannel": archiveChannel,
"invalidPrefix": invalidPrefix,
"invalidWelcomeMessage": invalidWelcomeMessage,
"invalidTicketLimit": invalidTicketLimit, "invalidTicketLimit": invalidTicketLimit,
"csrf": store.Get("csrf").(string), "csrf": store.Get("csrf").(string),
"pingEveryone": pingEveryone, "pingEveryone": pingEveryone,
"paneltitle": panelTitle, "paneltitle": panelSettings.Title,
"panelcontent": panelContent, "panelcontent": panelSettings.Content,
"panelcolour": strconv.FormatInt(int64(panelColour), 16), "panelcolour": strconv.FormatInt(int64(panelSettings.Colour), 16),
"usersCanClose": usersCanClose, "usersCanClose": usersCanClose,
}) })
} else { } else {

View File

@ -0,0 +1,157 @@
package manage
import (
"fmt"
"github.com/TicketsBot/GoPanel/config"
"github.com/TicketsBot/GoPanel/database/table"
"github.com/TicketsBot/GoPanel/utils"
"github.com/TicketsBot/GoPanel/utils/discord/objects"
"github.com/gin-gonic/contrib/sessions"
"github.com/gin-gonic/gin"
"strconv"
)
func UpdateSettingsHandler(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 !utils.Contains(config.Conf.Admins, userIdStr) && !guild.Owner && !table.IsAdmin(guildId, userId) {
ctx.Redirect(302, config.Conf.Server.BaseUrl) // TODO: 403 Page
return
}
// Get CSRF token
csrfCorrect := ctx.PostForm("csrf") == store.Get("csrf").(string)
if !csrfCorrect {
ctx.Redirect(302, "/")
return
}
// Get prefix
prefix := ctx.PostForm("prefix")
prefixValid := false
if prefix != "" && len(prefix) < 8 {
table.UpdatePrefix(guildId, prefix)
prefixValid = true
}
// Get welcome message
welcomeMessageValid := false
welcomeMessage := ctx.PostForm("welcomeMessage")
if welcomeMessage != "" && len(welcomeMessage) > 1000 {
table.UpdateWelcomeMessage(guildId, welcomeMessage)
welcomeMessageValid = true
}
// Get ticket limit
var limit int
limitStr := ctx.PostForm("ticketlimit")
// 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
ticketLimitValid := false
if limitStr != "" && utils.IsInt(limitStr) && limit >= 1 && limit <= 10 {
table.UpdateTicketLimit(guildId, limit)
ticketLimitValid = true
}
// Ping everyone
pingEveryone := ctx.PostForm("pingeveryone") == "on"
table.UpdatePingEveryone(guildId, pingEveryone)
// Get a list of actual category IDs
categories := make(chan []table.Channel)
go table.GetCategories(guildId, categories)
// Convert to category IDs
var categoryIds []string
for _, category := range <-categories {
categoryIds = append(categoryIds, strconv.Itoa(int(category.ChannelId)))
}
// Update category
categoryStr := ctx.PostForm("category")
if utils.Contains(categoryIds, categoryStr) {
// Error is impossible, as we check it's a valid channel already
category, _ := strconv.ParseInt(categoryStr, 10, 64)
table.UpdateChannelCategory(guildId, category)
}
// Archive channel
// Create a list of IDs
var channelIds []string
for _, c := range guild.Channels {
channelIds = append(channelIds, c.Id)
}
// Update or archive channel
archiveChannelStr := ctx.PostForm("archivechannel")
if utils.Contains(channelIds, archiveChannelStr) {
// Error is impossible, as we check it's a valid channel already
parsed, _ := strconv.ParseInt(archiveChannelStr, 10, 64)
table.UpdateArchiveChannel(guildId, parsed)
}
// Get panel title
panelTitle := ctx.PostForm("paneltitle")
if panelTitle != "" && len(panelTitle) <= 255 {
table.UpdatePanelTitle(guildId, panelTitle)
}
// Get panel content
panelContent := ctx.PostForm("panelcontent")
if panelContent != "" || len(panelContent) <= 2048 {
table.UpdatePanelContent(guildId, panelContent)
}
// Get panel colour
panelColourHex := ctx.PostForm("panelcolour")
if panelColourHex == "" {
panelColour, err := strconv.ParseUint(panelColourHex, 16, 32)
if err == nil {
table.UpdatePanelColour(guildId, int(panelColour))
}
}
// Users can close
usersCanClose := ctx.PostForm("userscanclose") == "on"
table.SetUserCanClose(guildId, usersCanClose)
ctx.Redirect(302, fmt.Sprintf("/manage/%d/settings?validPrefix=%t&validWelcomeMessage=%t&ticketLimitValid=%t", guildId, prefixValid, welcomeMessageValid, ticketLimitValid))
} else {
ctx.Redirect(302, "/login")
}
}

View File

@ -41,6 +41,7 @@ func StartServer() {
router.GET("/logout", root.LogoutHandler) router.GET("/logout", root.LogoutHandler)
router.GET("/manage/:id/settings", manage.SettingsHandler) router.GET("/manage/:id/settings", manage.SettingsHandler)
router.POST("/manage/:id/settings", manage.UpdateSettingsHandler)
router.GET("/manage/:id/logs/page/:page", manage.LogsHandler) router.GET("/manage/:id/logs/page/:page", manage.LogsHandler)
router.GET("/manage/:id/logs/view/:uuid", manage.LogViewHandler) router.GET("/manage/:id/logs/view/:uuid", manage.LogViewHandler)

View File

@ -0,0 +1,56 @@
package table
import (
"github.com/TicketsBot/GoPanel/database"
)
type Channel struct {
ChannelId int64 `gorm:"column:CHANNELID"`
GuildId int64 `gorm:"column:GUILDID"`
Name string `gorm:"column:NAME;type:VARCHAR(32)"`
Type int `gorm:"column:CHANNELTYPE;type:TINYINT(1)"`
}
func (Channel) TableName() string {
return "Channel"
}
func StoreChannel(channelId, guildId int64, name string, channelType int) {
channel := Channel{
ChannelId: channelId,
GuildId: guildId,
Name: name,
Type: channelType,
}
database.Database.Where(&Channel{ChannelId:channelId}).Assign(&channel).FirstOrCreate(&Channel{})
}
func DeleteChannel(channelId int64) {
var node Channel
database.Database.Where(Channel{ChannelId: channelId}).Take(&node)
database.Database.Delete(&node)
}
func GetCachedChannelsByGuild(guildId int64, res chan []Channel) {
var nodes []Channel
database.Database.Where(Channel{GuildId: guildId}).Find(&nodes)
res <- nodes
}
// Util function ig
func GetCategories(guildId int64, res chan []Channel) {
channelsChan := make(chan []Channel)
go GetCachedChannelsByGuild(guildId, channelsChan)
channels := <-channelsChan
var categories []Channel
for _, channel := range channels {
if channel.Type == 4 {
categories = append(categories, channel)
}
}
res <- categories
}

View File

@ -25,6 +25,30 @@ func UpdatePanelSettings(guildId int64, title string, content string, colour int
database.Database.Where(&PanelSettings{GuildId: guildId}).Assign(&settings).FirstOrCreate(&PanelSettings{}) database.Database.Where(&PanelSettings{GuildId: guildId}).Assign(&settings).FirstOrCreate(&PanelSettings{})
} }
func UpdatePanelTitle(guildId int64, title string) {
settings := PanelSettings{
Title: title,
}
database.Database.Where(&PanelSettings{GuildId: guildId}).Assign(&settings).FirstOrCreate(&PanelSettings{})
}
func UpdatePanelContent(guildId int64, content string) {
settings := PanelSettings{
Content: content,
}
database.Database.Where(&PanelSettings{GuildId: guildId}).Assign(&settings).FirstOrCreate(&PanelSettings{})
}
func UpdatePanelColour(guildId int64, colour int) {
settings := PanelSettings{
Colour: colour,
}
database.Database.Where(&PanelSettings{GuildId: guildId}).Assign(&settings).FirstOrCreate(&PanelSettings{})
}
func GetPanelSettings(guildId int64) PanelSettings { func GetPanelSettings(guildId int64) PanelSettings {
settings := PanelSettings{ settings := PanelSettings{
Title: "Open A Ticket", Title: "Open A Ticket",

View File

@ -11,7 +11,7 @@
{{end}} {{end}}
</div> </div>
<div class="card-body"> <div class="card-body">
<form> <form method="post">
<div class="row"> <div class="row">
<div class="col-md-5 pr-1"> <div class="col-md-5 pr-1">
<div class="form-group"> <div class="form-group">
@ -51,7 +51,7 @@
</div> </div>
<select class="form-control" name="archivechannel"> <select class="form-control" name="archivechannel">
{{range .channels}} {{range .channels}}
<option {{if .active}}selected{{end}} value="{{.channelid}}">{{.channelname}}</option> <option {{if eq .ChannelId $.archivechannel }}selected{{end}} value="{{.ChannelId}}">{{.Name}}</option>
{{end}} {{end}}
</select> </select>
</div> </div>
@ -62,7 +62,7 @@
<label>Channel Category</label> <label>Channel Category</label>
<select class="form-control" name="category"> <select class="form-control" name="category">
{{range .categories}} {{range .categories}}
<option {{if .active}}selected{{end}} value="{{.categoryid}}">{{.categoryname}}</option> <option {{if eq $.activecategory .ChannelId}}selected{{end}} value="{{.ChannelId}}">{{.Name}}</option>
{{end}} {{end}}
</select> </select>
</div> </div>

View File

@ -41,15 +41,3 @@ type Guild struct {
PremiumSubscriptionCount int `json:"premium_subscription_count"` PremiumSubscriptionCount int `json:"premium_subscription_count"`
PreferredLocale string `json:"preferred_locale"` PreferredLocale string `json:"preferred_locale"`
} }
func (g *Guild) GetCategories() []Channel {
var categories []Channel
for _, channel := range g.Channels {
if channel.Type == 4 {
categories = append(categories, channel)
}
}
return categories
}