package app import ( "fmt" "log" "net/http" "os" "time" "github.com/realTristan/disgoauth" ) const discordAuthType = "discord" var dc *disgoauth.Client = disgoauth.Init(&disgoauth.Client{ ClientID: os.Getenv(discordClientIDEnv), ClientSecret: os.Getenv(discordClientSecretEnv), RedirectURI: os.Getenv(discordRedirectEnv), Scopes: []string{disgoauth.ScopeIdentify}, }) func httpHandleDiscordLogin(w http.ResponseWriter, r *http.Request) { // check for existing session user, err := getCurrentUserFromSession(r) if err == nil && user.ID > 0 { http.Redirect(w, r, "/user", http.StatusFound) return } // check for code in url, if no code redirect to discord login code := r.URL.Query().Get("code") if code == "" { dc.RedirectHandler(w, r, "") return } // fetch discord user data using code accessToken, err := dc.GetOnlyAccessToken(code) if err != nil { httpHandleError(w, err) return } userData, err := disgoauth.GetUserData(accessToken) if err != nil { httpHandleError(w, err) } // user discord id to map to app user id discordID := userData["id"].(string) discordIDToken := fmt.Sprintf("id:%s", discordID) discordRecord, err := fetchUserAuthTokenRecordByTokenAndType(db, discordIDToken, discordAuthType) // create new user if existing not found if err != nil { user = UserRecord{} if err := createUserRecord(db, &user); err != nil { httpHandleError(w, err) return } discordRecord.UserID = user.ID discordRecord.Type = discordAuthType discordRecord.Token = discordIDToken discordRecord.ExpiresAt = time.Now().Add(time.Hour * 876000) discordRecord.ClientID = getUserClientID(r) if err := createUserAuthTokenRecord(db, &discordRecord); err != nil { httpHandleError(w, err) return } } // create sessiion cookie if err := httpCreateUserSession(w, r, discordRecord.UserID); err != nil { httpHandleError(w, err) return } log.Printf(" >> logged in via discord as user %d", discordRecord.UserID) http.Redirect(w, r, "/user", http.StatusFound) }