Mike Schwörer
358c238f3d
Some checks failed
Build Docker and Deploy / Run goext test-suite (push) Failing after 1m28s
92 lines
1.9 KiB
Go
92 lines
1.9 KiB
Go
package googleapi
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"gogs.mikescher.com/BlackForestBytes/goext/exerr"
|
|
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
|
"gogs.mikescher.com/BlackForestBytes/goext/timeext"
|
|
"io"
|
|
"net/http"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
type GoogleOAuth interface {
|
|
AccessToken() (string, error)
|
|
}
|
|
|
|
type oauth struct {
|
|
clientID string
|
|
clientSecret string
|
|
refreshToken string
|
|
|
|
lock sync.RWMutex
|
|
accessToken *string
|
|
expiryDate *time.Time
|
|
}
|
|
|
|
func NewGoogleOAuth(clientid string, clientsecret, refreshtoken string) GoogleOAuth {
|
|
return &oauth{
|
|
clientID: clientid,
|
|
clientSecret: clientsecret,
|
|
refreshToken: refreshtoken,
|
|
}
|
|
}
|
|
|
|
func (c *oauth) AccessToken() (string, error) {
|
|
c.lock.RLock()
|
|
if c.accessToken != nil && c.expiryDate != nil && (*c.expiryDate).After(time.Now()) {
|
|
c.lock.RUnlock()
|
|
return *c.accessToken, nil // still valid
|
|
}
|
|
c.lock.RUnlock()
|
|
|
|
httpclient := http.Client{}
|
|
|
|
url := fmt.Sprintf("https://oauth2.googleapis.com/token?client_id=%s&client_secret=%s&grant_type=%s&refresh_token=%s",
|
|
c.clientID,
|
|
c.clientSecret,
|
|
"refresh_token",
|
|
c.refreshToken)
|
|
|
|
req, err := http.NewRequest(http.MethodPost, url, nil)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
reqStartTime := time.Now()
|
|
|
|
res, err := httpclient.Do(req)
|
|
|
|
type response struct {
|
|
AccessToken string `json:"access_token"`
|
|
ExpiresIn int `json:"expires_in"`
|
|
Scope string `json:"scope"`
|
|
TokenType string `json:"token_type"`
|
|
}
|
|
|
|
var r response
|
|
|
|
data, err := io.ReadAll(res.Body)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
err = json.Unmarshal(data, &r)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
if r.ExpiresIn == 0 || r.AccessToken == "" {
|
|
return "", exerr.New(exerr.TypeGoogleResponse, "google oauth returned no response").Str("body", string(data)).Build()
|
|
}
|
|
|
|
c.lock.Lock()
|
|
c.expiryDate = langext.Ptr(reqStartTime.Add(timeext.FromSeconds(r.ExpiresIn - 10)))
|
|
c.accessToken = langext.Ptr(r.AccessToken)
|
|
c.lock.Unlock()
|
|
|
|
return r.AccessToken, nil
|
|
}
|