Finish porting panel

This commit is contained in:
2019-05-26 02:47:51 +01:00
parent bc3fa195c1
commit 208bdc03f3
43 changed files with 511 additions and 265 deletions

View File

@ -1 +0,0 @@
package database

View File

@ -20,21 +20,24 @@ func LogsHandler(ctx *gin.Context) {
if utils.IsLoggedIn(store) {
userIdStr := store.Get("userid").(string)
userId, err := utils.GetUserId(store); if err != nil {
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 {
guildId, err := strconv.ParseInt(guildIdStr, 10, 64)
if err != nil {
ctx.Redirect(302, config.Conf.Server.BaseUrl) // TODO: 404 Page
return
}
pageStr := ctx.Param("page")
page := 1
i, err := strconv.Atoi(pageStr); if err == nil {
i, err := strconv.Atoi(pageStr)
if err == nil {
if i > 0 {
page = i
}
@ -55,11 +58,51 @@ func LogsHandler(ctx *gin.Context) {
return
}
pageLimit := 30
// Get logs
// Get user ID from URL
var filteredUserId int64
if utils.IsInt(ctx.Query("userid")) {
filteredUserId, _ = strconv.ParseInt(ctx.Query("userid"), 10, 64)
}
utils.Respond(ctx, template.TemplateSettings.Render(map[string]interface{}{
"name": store.Get("name").(string),
// Get ticket ID from URL
var ticketId int
if utils.IsInt(ctx.Query("ticketid")) {
ticketId, _ = strconv.Atoi(ctx.Query("ticketid"))
}
// Get username from URL
username := ctx.Query("username")
// Get logs from DB
logs := table.GetFilteredTicketArchives(guildId, filteredUserId, username, ticketId)
// Select 30 logs + format them
var formattedLogs []map[string]interface{}
for i := (page - 1) * pageLimit; i < (page - 1) * pageLimit + pageLimit; i++ {
if i >= len(logs) {
break
}
log := logs[i]
formattedLogs = append(formattedLogs, map[string]interface{}{
"ticketid": log.TicketId,
"userid": log.User,
"username": log.Username,
"uuid": log.Uuid,
})
}
utils.Respond(ctx, template.TemplateLogs.Render(map[string]interface{}{
"name": store.Get("name").(string),
"guildId": guildIdStr,
"baseUrl": config.Conf.Server.BaseUrl,
"isPageOne": page == 1,
"previousPage": page - 1,
"nextPage": page + 1,
"logs": formattedLogs,
}))
} else {
ctx.Redirect(302, "/login")

View File

@ -3,6 +3,7 @@ package manage
import (
"encoding/base64"
"encoding/json"
"fmt"
"github.com/TicketsBot/GoPanel/app/http/template"
"github.com/TicketsBot/GoPanel/config"
"github.com/TicketsBot/GoPanel/database/table"
@ -24,14 +25,16 @@ func SettingsHandler(ctx *gin.Context) {
if utils.IsLoggedIn(store) {
userIdStr := store.Get("userid").(string)
userId, err := utils.GetUserId(store); if err != nil {
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 {
guildId, err := strconv.ParseInt(guildIdStr, 10, 64)
if err != nil {
ctx.Redirect(302, config.Conf.Server.BaseUrl) // TODO: 404 Page
return
}
@ -83,11 +86,8 @@ func SettingsHandler(ctx *gin.Context) {
table.UpdateTicketLimit(guildId, limit)
}
// Get a list of actual category IDs
categories := guild.GetCategories()
// /users/@me/guilds doesn't return channels, so we have to get them for the specific guild
if len(categories) == 0 {
if len(guild.Channels) == 0 {
var channels []objects.Channel
endpoint := guildendpoint.GetGuildChannels(int(guildId))
err = endpoint.Request(store, nil, nil, &channels)
@ -96,7 +96,6 @@ func SettingsHandler(ctx *gin.Context) {
// Not in guild
} else {
guild.Channels = channels
categories = guild.GetCategories()
// Update cache of categories now that we have them
guilds := table.GetGuilds(userIdStr)
@ -117,7 +116,8 @@ func SettingsHandler(ctx *gin.Context) {
// Insert updated guild
guilds = utils.Insert(guilds, index, guild)
marshalled, err := json.Marshal(guilds); if err != nil {
marshalled, err := json.Marshal(guilds)
if err != nil {
log.Error(err.Error())
} else {
table.UpdateGuilds(userIdStr, base64.StdEncoding.EncodeToString(marshalled))
@ -126,6 +126,10 @@ func SettingsHandler(ctx *gin.Context) {
}
}
// 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)
@ -149,19 +153,57 @@ func SettingsHandler(ctx *gin.Context) {
var formattedCategories []map[string]interface{}
for _, c := range categories {
formattedCategories = append(formattedCategories, map[string]interface{}{
"categoryid": c.Id,
"categoryid": c.Id,
"categoryname": c.Name,
"active": c.Id == strconv.Itoa(int(category)),
"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) {
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.Id == strconv.Itoa(int(archiveChannel)) {
fmt.Println(c.Name)
}
if c.Type == 0 {
formattedChannels = append(formattedChannels, map[string]interface{}{
"channelid": c.Id,
"channelname": c.Name,
"active": c.Id == strconv.Itoa(int(archiveChannel)),
})
}
}
utils.Respond(ctx, template.TemplateSettings.Render(map[string]interface{}{
"name": store.Get("name").(string),
"guildId": guildIdStr,
"prefix": prefix,
"name": store.Get("name").(string),
"guildId": guildIdStr,
"prefix": prefix,
"welcomeMessage": welcomeMessage,
"ticketLimit": limit,
"categories": formattedCategories,
"ticketLimit": limit,
"categories": formattedCategories,
"channels": formattedChannels,
}))
} else {
ctx.Redirect(302, "/login")

View File

@ -0,0 +1,84 @@
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"
"io/ioutil"
"net/http"
"strconv"
"time"
)
func LogViewHandler(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
}
uuid := ctx.Param("uuid")
cdnUrl := table.GetCdnUrl(guildId, uuid)
if cdnUrl == "" {
ctx.Redirect(302, fmt.Sprintf("/manage/%s/logs/page/1", guild.Id))
return
} else {
req, err := http.NewRequest("GET", cdnUrl, nil); if err != nil {
ctx.String(500, fmt.Sprintf("Failed to read log: %s", err.Error()))
return
}
client := &http.Client{}
client.Timeout = 3 * time.Second
res, err := client.Do(req); if err != nil {
ctx.String(500, fmt.Sprintf("Failed to read log: %s", err.Error()))
return
}
defer res.Body.Close()
content, err := ioutil.ReadAll(res.Body); if err != nil {
ctx.String(500, fmt.Sprintf("Failed to read log: %s", err.Error()))
return
}
ctx.String(200, string(content))
}
}
}

View File

@ -15,22 +15,22 @@ import (
"time"
)
type(
type (
TokenData struct {
ClientId string `qs:"client_id"`
ClientId string `qs:"client_id"`
ClientSecret string `qs:"client_secret"`
GrantType string `qs:"grant_type"`
Code string `qs:"code"`
RedirectUri string `qs:"redirect_uri"`
Scope string `qs:"scope"`
GrantType string `qs:"grant_type"`
Code string `qs:"code"`
RedirectUri string `qs:"redirect_uri"`
Scope string `qs:"scope"`
}
TokenResponse struct {
AccessToken string `json:"access_token"`
TokenType string `json:"token_type"`
ExpiresIn int `json:"expires_in"`
AccessToken string `json:"access_token"`
TokenType string `json:"token_type"`
ExpiresIn int `json:"expires_in"`
RefreshToken string `json:"refresh_token"`
Scope string `json:"scope"`
Scope string `json:"scope"`
}
)
@ -52,17 +52,19 @@ func CallbackHandler(ctx *gin.Context) {
return
}
res, err := discord.AccessToken(code); if err != nil {
res, err := discord.AccessToken(code)
if err != nil {
ctx.String(500, err.Error())
}
store.Set("access_token", res.AccessToken)
store.Set("refresh_token", res.RefreshToken)
store.Set("expiry", (time.Now().UnixNano() / int64(time.Second)) + int64(res.ExpiresIn))
store.Set("expiry", (time.Now().UnixNano()/int64(time.Second))+int64(res.ExpiresIn))
// Get ID + name
var currentUser objects.User
err = user.CurrentUser.Request(store, nil, nil, &currentUser); if err != nil {
err = user.CurrentUser.Request(store, nil, nil, &currentUser)
if err != nil {
ctx.String(500, err.Error())
return
}
@ -73,17 +75,19 @@ func CallbackHandler(ctx *gin.Context) {
log.Error(err.Error())
}
ctx.Redirect(302,config.Conf.Server.BaseUrl)
ctx.Redirect(302, config.Conf.Server.BaseUrl)
// Cache guilds because Discord takes like 2 whole seconds to return then
go func() {
var guilds []objects.Guild
err = user.CurrentUserGuilds.Request(store, nil, nil, &guilds); if err != nil {
err = user.CurrentUserGuilds.Request(store, nil, nil, &guilds)
if err != nil {
log.Error(err.Error())
return
}
marshalled, err := json.Marshal(guilds); if err != nil {
marshalled, err := json.Marshal(guilds)
if err != nil {
log.Error(err.Error())
return
}

View File

@ -20,7 +20,8 @@ func IndexHandler(ctx *gin.Context) {
if utils.IsLoggedIn(store) {
userIdStr := store.Get("userid").(string)
userId, err := utils.GetUserId(store); if err != nil {
userId, err := utils.GetUserId(store)
if err != nil {
ctx.String(500, err.Error())
return
}
@ -28,7 +29,8 @@ func IndexHandler(ctx *gin.Context) {
adminGuilds := make([]objects.Guild, 0)
adminGuildIds := table.GetAdminGuilds(userId)
for _, guild := range table.GetGuilds(userIdStr) {
guildId, err := strconv.ParseInt(guild.Id, 10, 64); if err != nil {
guildId, err := strconv.ParseInt(guild.Id, 10, 64)
if err != nil {
ctx.String(500, err.Error())
return
}
@ -41,7 +43,7 @@ func IndexHandler(ctx *gin.Context) {
var servers []map[string]string
for _, server := range adminGuilds {
element := map[string]string{
"serverid": server.Id,
"serverid": server.Id,
"servername": server.Name,
}
@ -49,13 +51,12 @@ func IndexHandler(ctx *gin.Context) {
}
utils.Respond(ctx, template.TemplateIndex.Render(map[string]interface{}{
"name": store.Get("name").(string),
"name": store.Get("name").(string),
"baseurl": config.Conf.Server.BaseUrl,
"servers": servers,
"empty": len(servers) == 0,
"empty": len(servers) == 0,
}))
} else {
ctx.Redirect(302, "/login")
}
}

View File

@ -53,6 +53,9 @@ func StartServer() {
// /manage/:id/logs/page/:page
router.GET("/manage/:id/logs/page/:page", manage.LogsHandler)
// /manage/:id/logs/view/:uuid
router.GET("/manage/:id/logs/view/:uuid", manage.LogViewHandler)
if err := router.Run(config.Conf.Server.Host); err != nil {
panic(err)
}

View File

@ -11,10 +11,10 @@ type Layout struct {
type Template struct {
compiled *mustache.Template
Layout Layout
Layout Layout
}
var(
var (
LayoutMain Layout
TemplateIndex Template
@ -35,20 +35,21 @@ func LoadLayouts() {
func LoadTemplates() {
TemplateIndex = Template{
compiled: loadTemplate("index"),
Layout: LayoutMain,
Layout: LayoutMain,
}
TemplateLogs = Template{
compiled: loadTemplate("logs"),
Layout: LayoutMain,
Layout: LayoutMain,
}
TemplateSettings = Template{
compiled: loadTemplate("settings"),
Layout: LayoutMain,
Layout: LayoutMain,
}
}
func loadLayout(name string) *mustache.Template {
tmpl, err := mustache.ParseFile(fmt.Sprintf("./public/templates/layouts/%s.mustache", name)); if err != nil {
tmpl, err := mustache.ParseFile(fmt.Sprintf("./public/templates/layouts/%s.mustache", name))
if err != nil {
panic(err)
}
@ -56,7 +57,8 @@ func loadLayout(name string) *mustache.Template {
}
func loadTemplate(name string) *mustache.Template {
tmpl, err := mustache.ParseFile(fmt.Sprintf("./public/templates/views/%s.mustache", name)); if err != nil {
tmpl, err := mustache.ParseFile(fmt.Sprintf("./public/templates/views/%s.mustache", name))
if err != nil {
panic(err)
}

View File

@ -5,46 +5,46 @@ import (
"io/ioutil"
)
type(
type (
Config struct {
Server Server
Oauth Oauth
Server Server
Oauth Oauth
MariaDB MariaDB
Bot Bot
Redis Redis
Bot Bot
Redis Redis
}
Server struct {
Host string
BaseUrl string
MainSite string
CsrfKey string
Host string
BaseUrl string
MainSite string
CsrfKey string
Ratelimit Ratelimit
Session Session
Session Session
}
Ratelimit struct {
Window int
Max int
Max int
}
Session struct {
Threads int
Secret string
Secret string
}
Oauth struct {
Id int64
Secret string
Id int64
Secret string
RedirectUri string
}
MariaDB struct {
Host string
Host string
Username string
Password string
Database string
Threads int
Threads int
}
Bot struct {
@ -52,22 +52,24 @@ type(
}
Redis struct {
Host string
Port int
Host string
Port int
Password string
}
)
var(
var (
Conf Config
)
func LoadConfig() {
raw, err := ioutil.ReadFile("config.toml"); if err != nil {
raw, err := ioutil.ReadFile("config.toml")
if err != nil {
panic(err)
}
_, err = toml.Decode(string(raw), &Conf); if err != nil {
_, err = toml.Decode(string(raw), &Conf)
if err != nil {
panic(err)
}
}

View File

@ -7,7 +7,7 @@ import (
"github.com/jinzhu/gorm"
)
var(
var (
Database gorm.DB
)
@ -18,9 +18,10 @@ func ConnectToDatabase() {
config.Conf.MariaDB.Password,
config.Conf.MariaDB.Host,
config.Conf.MariaDB.Database,
)
)
db, err := gorm.Open("mysql", uri); if err != nil {
db, err := gorm.Open("mysql", uri)
if err != nil {
panic(err)
}

View File

@ -0,0 +1,29 @@
package table
import (
"fmt"
"github.com/TicketsBot/GoPanel/database"
)
type ArchiveChannel struct {
Guild int64 `gorm:"column:GUILDID"`
Channel int64 `gorm:"column:CHANNELID"`
}
func (ArchiveChannel) TableName() string {
return "archivechannel"
}
func UpdateArchiveChannel(guildId int64, channelId int64) {
fmt.Println(channelId)
var channel ArchiveChannel
database.Database.Where(ArchiveChannel{Guild: guildId}).Assign(ArchiveChannel{Channel: channelId}).FirstOrCreate(&channel)
}
func GetArchiveChannel(guildId int64) int64 {
var channel ArchiveChannel
database.Database.Where(&ArchiveChannel{Guild: guildId}).First(&channel)
return channel.Channel
}

View File

@ -5,7 +5,7 @@ import (
)
type ChannelCategory struct {
GuildId int64 `gorm:"column:GUILDID"`
GuildId int64 `gorm:"column:GUILDID"`
Category int64 `gorm:"column:CATEGORYID"`
}

View File

@ -24,7 +24,8 @@ func UpdateGuilds(userId string, guilds string) {
func GetGuilds(userId string) []objects.Guild {
var cache GuildCache
database.Database.Where(&GuildCache{UserId: userId}).First(&cache)
decoded, err := base64.StdEncoding.DecodeString(cache.Guilds); if err != nil {
decoded, err := base64.StdEncoding.DecodeString(cache.Guilds)
if err != nil {
return make([]objects.Guild, 0)
}

View File

@ -3,10 +3,10 @@ package table
import "github.com/TicketsBot/GoPanel/database"
type PermissionNode struct {
GuildId int64 `gorm:"column:GUILDID"`
UserId int64 `gorm:"column:USERID"`
IsSupport bool `gorm:"column:ISSUPPORT"`
IsAdmin bool `gorm:"column:ISADMIN"`
GuildId int64 `gorm:"column:GUILDID"`
UserId int64 `gorm:"column:USERID"`
IsSupport bool `gorm:"column:ISSUPPORT"`
IsAdmin bool `gorm:"column:ISADMIN"`
}
func (PermissionNode) TableName() string {

View File

@ -5,8 +5,8 @@ import (
)
type Prefix struct {
GuildId int64 `gorm:"column:GUILDID"`
Prefix string `gorm:"column:PREFIX;type:varchar(8)"`
GuildId int64 `gorm:"column:GUILDID"`
Prefix string `gorm:"column:PREFIX;type:varchar(8)"`
}
func (Prefix) TableName() string {
@ -18,7 +18,7 @@ func UpdatePrefix(guildId int64, prefix string) {
}
func GetPrefix(guildId int64) string {
prefix := Prefix{Prefix:"t!"}
prefix := Prefix{Prefix: "t!"}
database.Database.Where(&Prefix{GuildId: guildId}).First(&prefix)
return prefix.Prefix

View File

@ -5,12 +5,12 @@ import (
)
type TicketArchive struct {
Uuid string `gorm:"column:UUID;type:varchar(36)"`
Guild int64 `gorm:"column:GUILDID"`
User int64 `gorm:"column:USERID"`
Uuid string `gorm:"column:UUID;type:varchar(36)"`
Guild int64 `gorm:"column:GUILDID"`
User int64 `gorm:"column:USERID"`
Username string `gorm:"column:USERNAME;type:varchar(32)"`
TicketId int `gorm:"column:TICKETID"`
CdnUrl string `gorm:"column:CDNURL;type:varchar(100)"`
TicketId int `gorm:"column:TICKETID"`
CdnUrl string `gorm:"column:CDNURL;type:varchar(100)"`
}
func (TicketArchive) TableName() string {
@ -19,7 +19,7 @@ func (TicketArchive) TableName() string {
func GetTicketArchives(guildId int64) []TicketArchive {
var archives []TicketArchive
database.Database.Where(&TicketArchive{Guild: guildId}).Find(&archives)
database.Database.Where(&TicketArchive{Guild: guildId}).Order("TICKETID desc").Find(&archives)
return archives
}
@ -38,7 +38,13 @@ func GetFilteredTicketArchives(guildId int64, userId int64, username string, tic
query = query.Where(&TicketArchive{TicketId: ticketId})
}
query.Find(&archives)
query.Order("TICKETID desc").Find(&archives)
return archives
}
func GetCdnUrl(guildId int64, uuid string) string {
var archive TicketArchive
database.Database.Where(&TicketArchive{Guild: guildId, Uuid: uuid}).First(&archive)
return archive.CdnUrl
}

View File

@ -6,7 +6,7 @@ import (
type TicketLimit struct {
GuildId int64 `gorm:"column:GUILDID"`
Limit int `gorm:"column:TICKETLIMIT"`
Limit int `gorm:"column:TICKETLIMIT"`
}
func (TicketLimit) TableName() string {

View File

@ -5,7 +5,7 @@ import (
)
type WelcomeMessage struct {
GuildId int64 `gorm:"column:GUILDID"`
GuildId int64 `gorm:"column:GUILDID"`
Message string `gorm:"column:MESSAGE;type:text"`
}
@ -18,7 +18,7 @@ func UpdateWelcomeMessage(guildId int64, message string) {
}
func GetWelcomeMessage(guildId int64) string {
message := WelcomeMessage{Message:"No message specified"}
message := WelcomeMessage{Message: "No message specified"}
database.Database.Where(&WelcomeMessage{GuildId: guildId}).First(&message)
return message.Message

View File

@ -60,12 +60,11 @@
</thead>
<tbody>
{{#logs}}
{{{baseUrl}}}
<tr>
<td>{{TICKETID}}</td>
<td>{{USERNAME}}</td>
<td>{{USERID}}</td>
<td><a href="{{baseUrl}}/logs/{{UUID}}">{{UUID}}</a></td>
<td>{{ticketid}}</td>
<td>{{username}}</td>
<td>{{userid}}</td>
<td><a href="{{baseUrl}}/manage/{{guildId}}/logs/view/{{uuid}}">{{uuid}}</a></td>
</tr>
{{/logs}}
</tbody>

View File

@ -64,6 +64,22 @@
</div>
</div>
<div class="row">
<div class="input-field col s12">
<p><b>Archive Channel</b></p>
<select name="archivechannel">
{{#channels}}
{{#active}}
<option value="{{channelid}}" selected>#{{channelname}}</option>
{{/active}}
{{^active}}
<option value="{{channelid}}">#{{channelname}}</option>
{{/active}}
{{/channels}}
</select>
</div>
</div>
<div class="row">
<div class="col s12 center-align">
<button class="btn waves-effect waves-light indigo darken-1" type="submit" name="action">Save

View File

@ -11,31 +11,31 @@ import (
"time"
)
type(
type (
TokenData struct {
ClientId string `qs:"client_id"`
ClientId string `qs:"client_id"`
ClientSecret string `qs:"client_secret"`
GrantType string `qs:"grant_type"`
Code string `qs:"code"`
RedirectUri string `qs:"redirect_uri"`
Scope string `qs:"scope"`
GrantType string `qs:"grant_type"`
Code string `qs:"code"`
RedirectUri string `qs:"redirect_uri"`
Scope string `qs:"scope"`
}
RefreshData struct {
ClientId string `qs:"client_id"`
ClientId string `qs:"client_id"`
ClientSecret string `qs:"client_secret"`
GrantType string `qs:"grant_type"`
GrantType string `qs:"grant_type"`
RefreshToken string `qs:"refresh_token"`
RedirectUri string `qs:"redirect_uri"`
Scope string `qs:"scope"`
RedirectUri string `qs:"redirect_uri"`
Scope string `qs:"scope"`
}
TokenResponse struct {
AccessToken string `json:"access_token"`
TokenType string `json:"token_type"`
ExpiresIn int `json:"expires_in"`
AccessToken string `json:"access_token"`
TokenType string `json:"token_type"`
ExpiresIn int `json:"expires_in"`
RefreshToken string `json:"refresh_token"`
Scope string `json:"scope"`
Scope string `json:"scope"`
}
)
@ -43,15 +43,16 @@ const TokenEndpoint = "https://discordapp.com/api/oauth2/token"
func AccessToken(code string) (TokenResponse, error) {
data := TokenData{
ClientId: strconv.Itoa(int(config.Conf.Oauth.Id)),
ClientId: strconv.Itoa(int(config.Conf.Oauth.Id)),
ClientSecret: config.Conf.Oauth.Secret,
GrantType: "authorization_code",
Code: code,
RedirectUri: config.Conf.Oauth.RedirectUri,
Scope: "identify guilds",
GrantType: "authorization_code",
Code: code,
RedirectUri: config.Conf.Oauth.RedirectUri,
Scope: "identify guilds",
}
res, err := tokenPost(data); if err != nil {
res, err := tokenPost(data)
if err != nil {
return TokenResponse{}, err
}
@ -65,15 +66,16 @@ func AccessToken(code string) (TokenResponse, error) {
func RefreshToken(refreshToken string) (TokenResponse, error) {
data := RefreshData{
ClientId: strconv.Itoa(int(config.Conf.Oauth.Id)),
ClientId: strconv.Itoa(int(config.Conf.Oauth.Id)),
ClientSecret: config.Conf.Oauth.Secret,
GrantType: "refresh_token",
GrantType: "refresh_token",
RefreshToken: refreshToken,
RedirectUri: config.Conf.Oauth.RedirectUri,
Scope: "identify guilds",
RedirectUri: config.Conf.Oauth.RedirectUri,
Scope: "identify guilds",
}
res, err := tokenPost(data); if err != nil {
res, err := tokenPost(data)
if err != nil {
return TokenResponse{}, err
}
@ -86,12 +88,14 @@ func RefreshToken(refreshToken string) (TokenResponse, error) {
}
func tokenPost(body ...interface{}) ([]byte, error) {
str, err := qs.Marshal(body[0]); if err != nil {
str, err := qs.Marshal(body[0])
if err != nil {
return nil, err
}
encoded := []byte(str)
req, err := http.NewRequest("POST", TokenEndpoint, bytes.NewBuffer([]byte(encoded))); if err != nil {
req, err := http.NewRequest("POST", TokenEndpoint, bytes.NewBuffer([]byte(encoded)))
if err != nil {
return nil, err
}
@ -100,12 +104,14 @@ func tokenPost(body ...interface{}) ([]byte, error) {
client := &http.Client{}
client.Timeout = 3 * time.Second
res, err := client.Do(req); if err != nil {
res, err := client.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
content, err := ioutil.ReadAll(res.Body); if err != nil {
content, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}

View File

@ -16,24 +16,24 @@ type RequestType string
type ContentType string
type AuthorizationType string
const(
GET RequestType = "GET"
POST RequestType = "POST"
const (
GET RequestType = "GET"
POST RequestType = "POST"
PATCH RequestType = "PATCH"
BEARER AuthorizationType = "Bearer"
BOT AuthorizationType = "BOT"
BOT AuthorizationType = "BOT"
ApplicationJson ContentType = "application/json"
ApplicationJson ContentType = "application/json"
ApplicationFormUrlEncoded ContentType = "application/x-www-form-urlencoded"
BASE_URL = "https://discordapp.com/api/v6"
)
type Endpoint struct {
RequestType RequestType
RequestType RequestType
AuthorizationType AuthorizationType
Endpoint string
Endpoint string
}
func (e *Endpoint) Request(store sessions.Session, contentType *ContentType, body interface{}, response interface{}) error {
@ -48,12 +48,14 @@ func (e *Endpoint) Request(store sessions.Session, contentType *ContentType, bod
// Encode body
var encoded []byte
if *contentType == ApplicationJson {
raw, err := json.Marshal(body); if err != nil {
raw, err := json.Marshal(body)
if err != nil {
return err
}
encoded = raw
} else if *contentType == ApplicationFormUrlEncoded {
str, err := qs.Marshal(body); if err != nil {
str, err := qs.Marshal(body)
if err != nil {
return err
}
encoded = []byte(str)
@ -80,33 +82,38 @@ func (e *Endpoint) Request(store sessions.Session, contentType *ContentType, bod
// Check if needs refresh
if (time.Now().UnixNano() / int64(time.Second)) > int64(expiry) {
res, err := RefreshToken(refreshToken); if err != nil {
res, err := RefreshToken(refreshToken)
if err != nil {
store.Clear()
_ = store.Save()
return errors.New("Please login again!")
}
store.Set("access_token", res.AccessToken)
store.Set("expiry", (time.Now().UnixNano() / int64(time.Second)) + int64(res.ExpiresIn))
store.Set("expiry", (time.Now().UnixNano()/int64(time.Second))+int64(res.ExpiresIn))
store.Set("refresh_token", res.RefreshToken)
accessToken = res.AccessToken
}
switch e.AuthorizationType{
case BEARER: req.Header.Set("Authorization", "Bearer " + accessToken)
case BOT: req.Header.Set("Authorization", "Bot " + config.Conf.Bot.Token)
switch e.AuthorizationType {
case BEARER:
req.Header.Set("Authorization", "Bearer "+accessToken)
case BOT:
req.Header.Set("Authorization", "Bot "+config.Conf.Bot.Token)
}
client := &http.Client{}
client.Timeout = 3 * time.Second
res, err := client.Do(req); if err != nil {
res, err := client.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
content, err := ioutil.ReadAll(res.Body); if err != nil {
content, err := ioutil.ReadAll(res.Body)
if err != nil {
return err
}

View File

@ -8,8 +8,8 @@ import (
func GetGuild(id int) discord.Endpoint {
return discord.Endpoint{
RequestType: discord.GET,
RequestType: discord.GET,
AuthorizationType: discord.BOT,
Endpoint: fmt.Sprintf("/guilds/%s", strconv.Itoa(id)),
Endpoint: fmt.Sprintf("/guilds/%s", strconv.Itoa(id)),
}
}

View File

@ -7,8 +7,8 @@ import (
func GetGuildChannels(id int) discord.Endpoint {
return discord.Endpoint{
RequestType: discord.GET,
RequestType: discord.GET,
AuthorizationType: discord.BOT,
Endpoint: fmt.Sprintf("/guilds/%d/channels", id),
Endpoint: fmt.Sprintf("/guilds/%d/channels", id),
}
}

View File

@ -3,7 +3,7 @@ package user
import "github.com/TicketsBot/GoPanel/utils/discord"
var CurrentUser = discord.Endpoint{
RequestType: discord.GET,
RequestType: discord.GET,
AuthorizationType: discord.BEARER,
Endpoint: "/users/@me",
Endpoint: "/users/@me",
}

View File

@ -3,7 +3,7 @@ package user
import "github.com/TicketsBot/GoPanel/utils/discord"
var CurrentUserGuilds = discord.Endpoint{
RequestType: discord.GET,
RequestType: discord.GET,
AuthorizationType: discord.BEARER,
Endpoint: "/users/@me/guilds",
Endpoint: "/users/@me/guilds",
}

View File

@ -1,16 +1,16 @@
package objects
type Activity struct {
Name string
Type int
Url string
Timestamps Timestamp
Name string
Type int
Url string
Timestamps Timestamp
ApplicationId string
Details string
State string
Party Party
Assets Asset
Secrets Secret
Instance bool
Flags int
Details string
State string
Party Party
Assets Asset
Secrets Secret
Instance bool
Flags int
}

View File

@ -2,7 +2,7 @@ package objects
type Asset struct {
LargeImage string
LargeText string
LargeText string
SmallImage string
SmallText string
SmallText string
}

View File

@ -1,22 +1,22 @@
package objects
type Channel struct {
Id string
Type int
GuildId string
Position int
Id string
Type int
GuildId string
Position int
PermissionsOverwrites []Overwrite
Name string
Topic string
Nsfw bool
LastMessageId string
Bitrate int
userLimit int
RateLimitPerUser int
Recipients []User
Icon string
Ownerid string
ApplicationId string
ParentId string
LastPinTimestamp string
Name string
Topic string
Nsfw bool
LastMessageId string
Bitrate int
userLimit int
RateLimitPerUser int
Recipients []User
Icon string
Ownerid string
ApplicationId string
ParentId string
LastPinTimestamp string
}

View File

@ -2,6 +2,6 @@ package objects
type ClientStatus struct {
Desktop string
Mobile string
Web string
Mobile string
Web string
}

View File

@ -1,11 +1,11 @@
package objects
type Emoji struct {
Id string
Name string
Roles []string
User User
Id string
Name string
Roles []string
User User
RequireColons bool
Managed bool
Animated bool
Managed bool
Animated bool
}

View File

@ -1,42 +1,42 @@
package objects
type Guild struct {
Id string
Name string
Icon string
Splash string
Owner bool
OwnerId string
Permissions int
Region string
AfkChannelid string
AfkTimeout int
EmbedEnabled bool
EmbedChannelId string
VerificationLevel int
Id string
Name string
Icon string
Splash string
Owner bool
OwnerId string
Permissions int
Region string
AfkChannelid string
AfkTimeout int
EmbedEnabled bool
EmbedChannelId string
VerificationLevel int
DefaultMessageNotifications int
ExplicitContentFilter int
Roles []Role
Emojis []Emoji
Features []string
MfaLevel int
ApplicationId string
WidgetEnabled bool
WidgetChannelId string
SystemChannelId string
JoinedAt string
Large bool
Unavailable bool
MemberCount int
VoiceStates []VoiceState
Members []Member
Channels []Channel
Presences []Presence
MaxPresences int
Maxmembers int
VanityUrlCode string
Description string
Banner string
ExplicitContentFilter int
Roles []Role
Emojis []Emoji
Features []string
MfaLevel int
ApplicationId string
WidgetEnabled bool
WidgetChannelId string
SystemChannelId string
JoinedAt string
Large bool
Unavailable bool
MemberCount int
VoiceStates []VoiceState
Members []Member
Channels []Channel
Presences []Presence
MaxPresences int
Maxmembers int
VanityUrlCode string
Description string
Banner string
}
func (g *Guild) GetCategories() []Channel {

View File

@ -1,10 +1,10 @@
package objects
type Member struct {
User User
Nick string
Roles []string
User User
Nick string
Roles []string
JoinedAt string
Deaf bool
Mute bool
Deaf bool
Mute bool
}

View File

@ -1,8 +1,8 @@
package objects
type Overwrite struct {
Id string
Type string
Id string
Type string
Allow int
Deny int
Deny int
}

View File

@ -1,6 +1,6 @@
package objects
type Party struct {
Id string
Id string
Size []int
}

View File

@ -1,11 +1,11 @@
package objects
type Presence struct {
User User
Roles []string
Game Activity
GuildId string
Status string
Activities []Activity
User User
Roles []string
Game Activity
GuildId string
Status string
Activities []Activity
ClientStatus ClientStatus
}

View File

@ -1,12 +1,12 @@
package objects
type Role struct {
Id string
Name string
Color int
Hoist bool
Position int
Id string
Name string
Color int
Hoist bool
Position int
Permissions int
Managed bool
Managed bool
Mentionable bool
}

View File

@ -1,7 +1,7 @@
package objects
type Secret struct {
Join string
Join string
Spectate string
Match string
Match string
}

View File

@ -2,5 +2,5 @@ package objects
type Timestamp struct {
Start int
End int
End int
}

View File

@ -1,12 +1,12 @@
package objects
type User struct {
Id string
Username string
Id string
Username string
Discriminator string
Avatar string
Verified bool
Email string
Flags int
PremiumType int
Avatar string
Verified bool
Email string
Flags int
PremiumType int
}

View File

@ -1,14 +1,14 @@
package objects
type VoiceState struct {
GuildId string
GuildId string
ChannelId string
UserId string
Member Member
UserId string
Member Member
SessionId string
Deaf bool
Mute bool
SelfDeaf bool
SelfMute bool
Suppress bool
Deaf bool
Mute bool
SelfDeaf bool
SelfMute bool
Suppress bool
}

View File

@ -3,7 +3,8 @@ package utils
import "io/ioutil"
func ReadFile(path string) (string, error) {
content, err := ioutil.ReadFile(path); if err != nil {
content, err := ioutil.ReadFile(path)
if err != nil {
return "", err
}

View File

@ -22,7 +22,7 @@ func Contains(s interface{}, elem interface{}) bool {
return false
}
func Insert(slice []objects.Guild, index int , value objects.Guild) []objects.Guild {
func Insert(slice []objects.Guild, index int, value objects.Guild) []objects.Guild {
// Grow the slice by one element.
slice = slice[0 : len(slice)+1]
// Use copy to move the upper part of the slice out of the way and open a hole.