package main import ( "encoding/json" "io" "log" "net/http" "os" "strconv" // "example.com/lib/dbcommands" "github.com/gin-gonic/gin" "github.com/pelletier/go-toml/v2" "github.com/ravener/discord-oauth2" "github.com/xyproto/randomstring" "golang.org/x/oauth2" ) type appConfig struct { OAuth struct { ClientID string ClientSecret string RedirectUrl string } } type discordUser struct { Id string Username string Avatar string Discriminator string Public_Flags float64 Flags float64 Banner string Accent_Color float64 Global_Name string Avatar_Decoration_Data struct { Asset string Sku_Id string Expires_At string } Collectibles string Banner_Color string Clan string Primary_Guild string Mfa_Eneabled bool Locale string Premium_Type float64 } var config appConfig var oauthConfig *oauth2.Config var oauthToken *oauth2.Token func parseConfig(configPath string) { configFile, err := os.Open(configPath) if err != nil { log.Fatal(err) } configFileContent, err := io.ReadAll(configFile) if err != nil { log.Fatal(err) } err = toml.Unmarshal(configFileContent, &config) if err != nil { log.Fatal(err) } } func createDiscordOAuthConfig(clientId string, clientSecret string, redirectUrl string) *oauth2.Config { config := &oauth2.Config{ ClientID: clientId, ClientSecret: clientSecret, RedirectURL: redirectUrl, Scopes: []string{discord.ScopeIdentify}, Endpoint: discord.Endpoint, } return config } func loginDisplay(context *gin.Context) { if oauthToken.Valid() { context.Redirect(http.StatusTemporaryRedirect, "/dashboard") } else { context.HTML(http.StatusOK, "root.html", gin.H{ "message": "hello, world!", }) } } func loginRedirect(context *gin.Context) { context.Redirect(302, oauthConfig.AuthCodeURL(context.GetString("state"))) } func authCallback(context *gin.Context) { oauthState := randomstring.CookieFriendlyString(32) context.Set("state", oauthState) var err error oauthToken, err = oauthConfig.Exchange(context.Request.Context(), context.Query("code")) if err != nil { context.HTML(http.StatusInternalServerError, "internalservererror.html", gin.H{ "message": "internalservererror", }) } context.Redirect(http.StatusTemporaryRedirect, "/dashboard") } func getDiscordUserInfo(context *gin.Context) discordUser { response, err := oauthConfig.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.HTML(http.StatusInternalServerError, "internalservererror.html", gin.H{ "message": responseMessage, }) } defer response.Body.Close() body, err := io.ReadAll(response.Body) if err != nil { context.HTML(http.StatusInternalServerError, "internalservererror.html", gin.H{ "message": err.Error(), }) } var discordUserInfo discordUser json.Unmarshal(body, &discordUserInfo) return discordUserInfo } func dashboardDisplay(context *gin.Context) { if oauthToken.Valid() { userInfo := getDiscordUserInfo(context) context.HTML(http.StatusOK, "dashboard.html", gin.H{ "discordUser": gin.H{ "id": userInfo.Id, "username": userInfo.Username, "avatar": userInfo.Avatar, "discriminator": userInfo.Discriminator, "public_flags": userInfo.Public_Flags, "flags": userInfo.Flags, "banner": userInfo.Banner, "accent_color": strconv.FormatFloat(userInfo.Accent_Color, 'f', 0, 64), "global_name": userInfo.Global_Name, "avatar_decoration_data": gin.H{ "asset": userInfo.Avatar_Decoration_Data.Asset, "sku_id": userInfo.Avatar_Decoration_Data.Sku_Id, "expires_at": userInfo.Avatar_Decoration_Data.Expires_At, }, "collectibles": userInfo.Collectibles, "banner_color": userInfo.Banner_Color, "clan": userInfo.Clan, "primary_guild": userInfo.Primary_Guild, "mfa_enabled": userInfo.Mfa_Eneabled, "locale": userInfo.Locale, "premium_type": userInfo.Premium_Type, }, }) } else { context.Redirect(http.StatusTemporaryRedirect, "/") } } func main() { // db := dbcommands.InitializeDatabase() parseConfig("config.toml") oauthConfig = createDiscordOAuthConfig(config.OAuth.ClientID, config.OAuth.ClientSecret, config.OAuth.RedirectUrl) app := gin.Default() app.LoadHTMLGlob("src/templates/*.html") app.Static("/public", "./public") app.GET("/", loginDisplay) app.GET("/login", loginRedirect) app.GET("/auth/callback", authCallback) app.GET("/dashboard", dashboardDisplay) app.Run(":8080") }