This commit is contained in:
darwincereska
2026-03-05 21:13:16 -05:00
parent 657722a130
commit 734c56eace
4 changed files with 111 additions and 2 deletions

1
.gitignore vendored
View File

@@ -26,5 +26,4 @@
.DS_Store
Thumbs.db
token/
token.json

View File

@@ -0,0 +1,21 @@
version: "3"
tasks:
docker-build:
desc: Builds a docker image for linux/amd64
cmd: docker buildx build --platform linux/amd64 -t autocal:latest .
docker-tag:
desc: Tag docker build
cmd: docker tag autocal:latest git.darwincereska.dev/darwincereska/autocal:latest
docker-push:
desc: Push to repository
cmd: docker push git.darwincereska.dev/darwincereska/autocal:latest
docker-all:
desc: Build, tag, and release docker image
cmds:
- task docker-build
- task docker-tag
- task docker-push

View File

@@ -1 +1 @@
{"installed":{"client_id":"456144269477-cgd4f7fsbl5n5m4n52s9f63ep10sf2n9.apps.googleusercontent.com","project_id":"autocal-489320","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://oauth2.googleapis.com/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_secret":"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","redirect_uris":["http://localhost:4444/callback"]}}
{"web":{"client_id":"456144269477-4cb92rb26tv07tjlo0dmrvnte0p58rt8.apps.googleusercontent.com","project_id":"autocal-489320","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://oauth2.googleapis.com/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_secret":"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","redirect_uris":["https://autocal.darwincereska.dev/callback"]}}

89
token/token.go Normal file
View File

@@ -0,0 +1,89 @@
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)
}