78 lines
1.5 KiB
Go
78 lines
1.5 KiB
Go
|
|
package oauth
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"crypto/rand"
|
||
|
|
"fmt"
|
||
|
|
"log"
|
||
|
|
"net/http"
|
||
|
|
"sync"
|
||
|
|
|
||
|
|
"golang.org/x/oauth2"
|
||
|
|
)
|
||
|
|
|
||
|
|
func GenerateToken(
|
||
|
|
ctx *context.Context,
|
||
|
|
oauth2Config *oauth2.Config,
|
||
|
|
) (*oauth2.Token, error) {
|
||
|
|
verifier := oauth2.GenerateVerifier()
|
||
|
|
|
||
|
|
state := rand.Text()
|
||
|
|
|
||
|
|
var token *oauth2.Token
|
||
|
|
wg := sync.WaitGroup{}
|
||
|
|
|
||
|
|
var server http.Server
|
||
|
|
server.Addr = "127.0.0.1"
|
||
|
|
server.Handler = http.HandlerFunc(
|
||
|
|
func(w http.ResponseWriter, r *http.Request) {
|
||
|
|
code := r.URL.Query().Get("code")
|
||
|
|
scope := r.URL.Query().Get("scope")
|
||
|
|
resState := r.URL.Query().Get("state")
|
||
|
|
|
||
|
|
if len(code) == 0 || len(scope) == 0 || resState != state {
|
||
|
|
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
t, err := oauth2Config.Exchange(*ctx, code, oauth2.VerifierOption(verifier))
|
||
|
|
if err != nil {
|
||
|
|
log.Fatalf("Could not exchange OAuth2 code: %v", err)
|
||
|
|
http.Error( w,
|
||
|
|
fmt.Sprintf("Could not exchange OAuth2 code: %v", err),
|
||
|
|
http.StatusBadRequest,
|
||
|
|
)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
token = t
|
||
|
|
http.Error(
|
||
|
|
w,
|
||
|
|
"Authentication successful! You may now close this tab.",
|
||
|
|
http.StatusOK,
|
||
|
|
)
|
||
|
|
if f, ok := w.(http.Flusher); ok {
|
||
|
|
f.Flush()
|
||
|
|
}
|
||
|
|
|
||
|
|
wg.Done()
|
||
|
|
server.Close()
|
||
|
|
},
|
||
|
|
)
|
||
|
|
|
||
|
|
url := oauth2Config.AuthCodeURL(
|
||
|
|
state,
|
||
|
|
oauth2.AccessTypeOffline,
|
||
|
|
oauth2.S256ChallengeOption(verifier),
|
||
|
|
)
|
||
|
|
log.Printf("Log in with Twitch: %s\n\n", url)
|
||
|
|
|
||
|
|
wg.Add(1)
|
||
|
|
if err := server.ListenAndServe(); err != http.ErrServerClosed {
|
||
|
|
return nil, fmt.Errorf("http: %v", err)
|
||
|
|
}
|
||
|
|
wg.Wait()
|
||
|
|
|
||
|
|
return token, nil
|
||
|
|
}
|