84 lines
1.7 KiB
Go
84 lines
1.7 KiB
Go
package googleapi
|
|
|
|
import (
|
|
"encoding/json"
|
|
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
|
"gogs.mikescher.com/BlackForestBytes/goext/timeext"
|
|
"io"
|
|
"net/http"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
type GoogleOAuth interface {
|
|
}
|
|
|
|
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{}
|
|
|
|
req, err := http.NewRequest(http.MethodPost, "https://oauth2.googleapis.com/token", nil)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
req.URL.Query().Add("client_id", c.clientID)
|
|
req.URL.Query().Add("client_secret", c.clientSecret)
|
|
req.URL.Query().Add("grant_type", "refresh_token")
|
|
req.URL.Query().Add("refresh_token", c.refreshToken)
|
|
|
|
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
|
|
}
|
|
|
|
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
|
|
}
|