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, }) }