2020-07-08 13:34:15 +01:00

128 lines
3.3 KiB
Go

package root
import (
"fmt"
"github.com/TicketsBot/GoPanel/config"
dbclient "github.com/TicketsBot/GoPanel/database"
"github.com/TicketsBot/GoPanel/utils"
"github.com/TicketsBot/GoPanel/utils/discord"
userEndpoint "github.com/TicketsBot/GoPanel/utils/discord/endpoints/user"
"github.com/TicketsBot/database"
"github.com/apex/log"
"github.com/gin-gonic/contrib/sessions"
"github.com/gin-gonic/gin"
"github.com/rxdn/gdl/objects/guild"
"github.com/rxdn/gdl/objects/user"
"strings"
"time"
)
type (
TokenData struct {
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"`
}
TokenResponse struct {
AccessToken string `json:"access_token"`
TokenType string `json:"token_type"`
ExpiresIn int `json:"expires_in"`
RefreshToken string `json:"refresh_token"`
Scope string `json:"scope"`
}
)
func CallbackHandler(ctx *gin.Context) {
store := sessions.Default(ctx)
if store == nil {
return
}
defer store.Save()
if utils.IsLoggedIn(store) && store.Get("has_guilds") == true {
ctx.Redirect(302, config.Conf.Server.BaseUrl)
return
}
code, ok := ctx.GetQuery("code")
if !ok {
utils.ErrorPage(ctx, 400, "Discord provided invalid Oauth2 code")
return
}
res, err := discord.AccessToken(code)
if err != nil {
utils.ErrorPage(ctx, 500, err.Error())
return
}
store.Set("access_token", res.AccessToken)
store.Set("refresh_token", res.RefreshToken)
store.Set("expiry", (time.Now().UnixNano()/int64(time.Second))+int64(res.ExpiresIn))
// Get ID + name
var currentUser user.User
err, _ = userEndpoint.CurrentUser.Request(store, nil, nil, &currentUser)
if err != nil {
ctx.String(500, err.Error())
return
}
store.Set("csrf", utils.RandStringRunes(32))
store.Set("userid", currentUser.Id)
store.Set("name", currentUser.Username)
store.Set("avatar", currentUser.AvatarUrl(256))
store.Save()
var guilds []guild.Guild
err, _ = userEndpoint.CurrentUserGuilds.Request(store, nil, nil, &guilds)
if err != nil {
log.Error(err.Error())
handleRedirect(ctx)
return
}
store.Set("has_guilds", true)
store.Save()
var wrappedGuilds []database.UserGuild
// endpoint's partial guild doesn't include ownerid
// we only user cached guilds on the index page, so it doesn't matter if we don't have have the real owner id
// if the user isn't the owner, as we pull from the cache on other endpoints
for _, guild := range guilds {
if guild.Owner {
guild.OwnerId = currentUser.Id
}
wrappedGuilds = append(wrappedGuilds, database.UserGuild{
GuildId: guild.Id,
Name: guild.Name,
Owner: guild.Owner,
UserPermissions: int32(guild.Permissions),
Icon: guild.Icon,
})
}
if err := dbclient.Client.UserGuilds.Set(currentUser.Id, wrappedGuilds); err != nil {
log.Error(err.Error())
}
handleRedirect(ctx)
}
func handleRedirect(ctx *gin.Context) {
state := strings.Split(ctx.Query("state"), ".")
if len(state) == 3 && state[0] == "viewlog" {
ctx.Redirect(302, fmt.Sprintf("%s/manage/%s/logs/view/%s", config.Conf.Server.BaseUrl, state[1], state[2]))
} else {
ctx.Redirect(302, config.Conf.Server.BaseUrl)
}
}