Files
autocal/token/token.go
darwincereska 734c56eace temp
2026-03-05 21:13:16 -05:00

90 lines
2.1 KiB
Go

package token
import (
"context"
"encoding/json"
"fmt"
"net/http"
"os"
"time"
"github.com/charmbracelet/log"
"golang.org/x/oauth2"
)
// Return OAuth2 Client
func GetClient(config *oauth2.Config) *http.Client {
// The file token.json stores the user's access and refresh tokens, and is
// created automatically when the autorization flow completes for the first time
tokFile := "token.json"
tok, err := GetTokenFromFile(tokFile)
if err != nil {
tok = GetTokenFromWeb(config)
SaveToken(tokFile, tok)
}
return config.Client(context.Background(), tok)
}
// Request a token from the web
func GetTokenFromWeb(config *oauth2.Config) *oauth2.Token {
// Simple HTTP callback handler
codeCh := make(chan string)
srv := &http.Server{Addr: ":4444"}
http.HandleFunc("/callback", func(w http.ResponseWriter, r *http.Request) {
code := r.URL.Query().Get("code")
fmt.Fprint(w, "Authorization successful! You can close this tab.")
codeCh <- code
})
// Start in background
go func() {
srv.ListenAndServe()
}()
authURL := config.AuthCodeURL("state-token", oauth2.AccessTypeOffline, oauth2.ApprovalForce)
log.Info("Go to the following link in your browser and then type the authorization code:")
fmt.Println(authURL)
// Get authCode from channel
authCode := <-codeCh
tok, err := config.Exchange(context.TODO(), authCode)
if err != nil {
log.Fatal("Unable to retrieve token from web", "err", err)
}
ctxShutdown, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
srv.Shutdown(ctxShutdown)
return tok
}
// Retrieves a token from a file
func GetTokenFromFile(file string) (*oauth2.Token, error) {
f, err := os.Open(file)
if err != nil {
return nil, err
}
defer f.Close()
tok := &oauth2.Token{}
err = json.NewDecoder(f).Decode(tok)
return tok, err
}
// Saves a token to a file path
func SaveToken(path string, token *oauth2.Token) {
log.Info("Saving credential file to", "path", path)
f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
log.Fatal("Unable to cache oauth token", "err", err)
}
defer f.Close()
json.NewEncoder(f).Encode(token)
}