168 lines
4.8 KiB
Go
168 lines
4.8 KiB
Go
![]() |
package api
|
||
|
|
||
|
import (
|
||
|
"encoding/json"
|
||
|
"io"
|
||
|
"log"
|
||
|
"net/http"
|
||
|
|
||
|
authdiscord "example.com/auth/discord"
|
||
|
configserver "example.com/config/server"
|
||
|
databasecommands "example.com/database/commands"
|
||
|
databasemodels "example.com/database/models"
|
||
|
|
||
|
"github.com/gin-gonic/gin"
|
||
|
"github.com/xyproto/randomstring"
|
||
|
"golang.org/x/oauth2"
|
||
|
"gorm.io/gorm"
|
||
|
)
|
||
|
|
||
|
var GlobalDatabase *gorm.DB
|
||
|
var GlobalConfig configserver.AppConfig
|
||
|
var GlobalOAuth *oauth2.Config
|
||
|
|
||
|
func LoginRedirect(context *gin.Context) {
|
||
|
context.Redirect(302, GlobalOAuth.AuthCodeURL(context.GetString("state")))
|
||
|
}
|
||
|
|
||
|
func LogoutRedirect(context *gin.Context) {
|
||
|
oauthTokenJSON, err := context.Cookie("discord-oauthtoken")
|
||
|
if err == nil {
|
||
|
databasecommands.LogoutDatabaseUser(GlobalDatabase, oauthTokenJSON)
|
||
|
context.SetCookie("discord-oauthtoken", "", -1, "", GlobalConfig.API.Domain, false, true)
|
||
|
} else {
|
||
|
log.Println(err)
|
||
|
}
|
||
|
context.Redirect(http.StatusTemporaryRedirect, "http://localhost:15995/")
|
||
|
}
|
||
|
|
||
|
func AuthCallback(context *gin.Context) {
|
||
|
oauthState := randomstring.CookieFriendlyString(32)
|
||
|
context.Set("state", oauthState)
|
||
|
var err error
|
||
|
oauthToken, err := GlobalOAuth.Exchange(context.Request.Context(), context.Query("code"))
|
||
|
if err != nil {
|
||
|
context.Redirect(http.StatusInternalServerError, "http://localhost:15995/")
|
||
|
}
|
||
|
oauthTokenJSON, _ := json.Marshal(oauthToken)
|
||
|
context.SetCookie("discord-oauthtoken", string(oauthTokenJSON), 0, "", GlobalConfig.API.Domain, false, false)
|
||
|
user := GetDiscordUser(context, oauthToken)
|
||
|
CreateOrUpdateUser(context, oauthToken, user)
|
||
|
context.Redirect(http.StatusTemporaryRedirect, "http://localhost:15995/dashboard")
|
||
|
}
|
||
|
|
||
|
func GetDiscordUser(context *gin.Context, oauthToken *oauth2.Token) authdiscord.DiscordUser {
|
||
|
response, err := GlobalOAuth.Client(context.Request.Context(), oauthToken).Get("https://discord.com/api/users/@me")
|
||
|
if err != nil || response.StatusCode != 200 {
|
||
|
responseMessage := ""
|
||
|
if err != nil {
|
||
|
responseMessage = err.Error()
|
||
|
} else {
|
||
|
responseMessage = response.Status
|
||
|
}
|
||
|
context.JSON(http.StatusInternalServerError, gin.H{
|
||
|
"message": responseMessage,
|
||
|
})
|
||
|
}
|
||
|
defer response.Body.Close()
|
||
|
body, err := io.ReadAll(response.Body)
|
||
|
if err != nil {
|
||
|
context.JSON(http.StatusInternalServerError, gin.H{
|
||
|
"message": err.Error(),
|
||
|
})
|
||
|
}
|
||
|
var user authdiscord.DiscordUser
|
||
|
json.Unmarshal(body, &user)
|
||
|
return user
|
||
|
}
|
||
|
|
||
|
func CreateOrUpdateUser(context *gin.Context, oauthToken *oauth2.Token, user authdiscord.DiscordUser) {
|
||
|
oauthTokenJSON, err := json.Marshal(oauthToken)
|
||
|
if err != nil {
|
||
|
log.Println(err)
|
||
|
}
|
||
|
dbUser := databasemodels.User{
|
||
|
DisplayName: user.Global_Name,
|
||
|
Username: user.Username,
|
||
|
Id: user.Id,
|
||
|
Avatar: user.Avatar,
|
||
|
AvatarDecoration: user.Avatar_Decoration_Data.Asset,
|
||
|
LoginToken: string(oauthTokenJSON),
|
||
|
LoggedIn: true,
|
||
|
}
|
||
|
if databasecommands.DatabaseUserExists(GlobalDatabase, user.Id) {
|
||
|
dbOAuthToken := databasecommands.GetDatabaseUserToken(GlobalDatabase, user.Id)
|
||
|
if dbOAuthToken == "" {
|
||
|
context.SetCookie("discord-oauthtoken", string(oauthTokenJSON), 0, "", GlobalConfig.API.Domain, false, false)
|
||
|
err := databasecommands.UpdateDatabaseUser(GlobalDatabase, dbUser)
|
||
|
if err != nil {
|
||
|
log.Println(err)
|
||
|
}
|
||
|
} else {
|
||
|
context.SetCookie("discord-oauthtoken", dbOAuthToken, 0, "", GlobalConfig.API.Domain, false, false)
|
||
|
}
|
||
|
} else {
|
||
|
err := databasecommands.CreateDatabaseUser(GlobalDatabase, dbUser)
|
||
|
if err != nil {
|
||
|
log.Println(err)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func GetDashboardInfo(context *gin.Context) {
|
||
|
oauthTokenJSON, err := context.Cookie("discord-oauthtoken")
|
||
|
if err == nil {
|
||
|
var oauthToken *oauth2.Token
|
||
|
err := json.Unmarshal([]byte(oauthTokenJSON), &oauthToken)
|
||
|
if err == nil {
|
||
|
if oauthToken.Valid() {
|
||
|
user := GetDiscordUser(context, oauthToken)
|
||
|
if databasecommands.DatabaseUserLoggedIn(GlobalDatabase, user.Id) {
|
||
|
context.JSON(http.StatusOK, user)
|
||
|
return
|
||
|
} else {
|
||
|
context.Redirect(http.StatusTemporaryRedirect, "http://localhost:31337/logout")
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
} else {
|
||
|
log.Println(err)
|
||
|
}
|
||
|
} else {
|
||
|
log.Println(err)
|
||
|
}
|
||
|
context.Redirect(http.StatusTemporaryRedirect, "http://localhost:15995/")
|
||
|
}
|
||
|
|
||
|
func IsUserAuthorized(context *gin.Context) {
|
||
|
oauthTokenJSON, err := context.Cookie("discord-oauthtoken")
|
||
|
if err == nil {
|
||
|
var oauthToken *oauth2.Token
|
||
|
err := json.Unmarshal([]byte(oauthTokenJSON), &oauthToken)
|
||
|
if err == nil {
|
||
|
if oauthToken.Valid() {
|
||
|
user := GetDiscordUser(context, oauthToken)
|
||
|
if databasecommands.DatabaseUserLoggedIn(GlobalDatabase, user.Id) {
|
||
|
context.JSON(http.StatusOK, gin.H{
|
||
|
"message": true,
|
||
|
})
|
||
|
} else {
|
||
|
context.JSON(http.StatusUnauthorized, gin.H{
|
||
|
"message": true,
|
||
|
})
|
||
|
}
|
||
|
return
|
||
|
} else {
|
||
|
log.Println(err)
|
||
|
}
|
||
|
} else {
|
||
|
log.Println(err)
|
||
|
}
|
||
|
} else {
|
||
|
log.Println(err)
|
||
|
}
|
||
|
context.JSON(http.StatusUnauthorized, gin.H{
|
||
|
"message": false,
|
||
|
})
|
||
|
}
|