diff --git a/main.go b/main.go index 1e12443..721767e 100644 --- a/main.go +++ b/main.go @@ -730,10 +730,21 @@ func main() { Shard = flag.String("s", "", "Shard ID") ShardCount = flag.String("c", "", "Number of shards") Owner = flag.String("o", "", "Owner ID") + Port = flag.Int("p", 0, "Web server port") + Ci = flag.Int("ci", 0, "ClientID") + Cs = flag.String("cs", "", "ClientSecret") err error ) flag.Parse() + // Start Webserver if a valid port is provided and if ClientID and ClientSecret are set + if *Port != 0 && *Port >= 1 && *Ci != 0 && *Cs != "" { + log.Infoln("Starting web server on port " + strconv.Itoa(*Port)) + go startWebServer(strconv.Itoa(*Port), strconv.Itoa(*Ci), *Cs) + } else { + log.Infoln("Required web server arguments missing or invalid. Skipping web server start.") + } + if *Owner != "" { OWNER = *Owner } diff --git a/webserver.go b/webserver.go new file mode 100644 index 0000000..224dc42 --- /dev/null +++ b/webserver.go @@ -0,0 +1,78 @@ +package main + +import ( + "fmt" + "net/http" + + "github.com/bwmarrin/discordgo" + "golang.org/x/oauth2" +) + +const htmlIndex = ` +Log in with discord + +` + +var ( + discordOauthConfig = &oauth2.Config{ + RedirectURL: "", + ClientID: "", + ClientSecret: "", + Scopes: []string{"connections", + "email", + "identify", + "guilds"}, + Endpoint: *endp, + } + // Some random string, random for each request + oauthStateString = "random" + endp = &oauth2.Endpoint{ + AuthURL: "https://discordapp.com/api/oauth2/authorize", + TokenURL: "https://discordapp.com/api/oauth2/token", + } +) + +// startWebServer with the port provided +func startWebServer(port string, ci string, cs string) { + discordOauthConfig.ClientID = ci + discordOauthConfig.ClientSecret = cs + http.HandleFunc("/", handleMain) + http.HandleFunc("/discordLogin", handlediscordLogin) + http.HandleFunc("/discordCallback", handlediscordCallback) + fmt.Println(http.ListenAndServe(":"+port, nil)) +} + +func handleMain(w http.ResponseWriter, r *http.Request) { + discordOauthConfig.RedirectURL = "http://" + r.Host + "/discordCallback" + fmt.Fprintf(w, htmlIndex) +} + +func handlediscordLogin(w http.ResponseWriter, r *http.Request) { + url := discordOauthConfig.AuthCodeURL(oauthStateString) + http.Redirect(w, r, url, http.StatusTemporaryRedirect) +} + +func handlediscordCallback(w http.ResponseWriter, r *http.Request) { + state := r.FormValue("state") + if state != oauthStateString { + fmt.Printf("invalid oauth state, expected '%s', got '%s'\n", oauthStateString, state) + http.Redirect(w, r, "/", http.StatusTemporaryRedirect) + return + } + + code := r.FormValue("code") + token, err := discordOauthConfig.Exchange(oauth2.NoContext, code) + if err != nil { + fmt.Println("Code exchange failed with ", err) + http.Redirect(w, r, "/", http.StatusTemporaryRedirect) + return + } + + dg, err := discordgo.New("Bearer " + token.AccessToken) + if err != nil { + fmt.Println("Error while creating discord session: ", err) + return + } + user, _ := dg.User("@me") + fmt.Fprintf(w, user.Username) +}