88
drivers/febbox/oauth2.go
Normal file
88
drivers/febbox/oauth2.go
Normal file
@ -0,0 +1,88 @@
|
||||
package febbox
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"golang.org/x/oauth2"
|
||||
"golang.org/x/oauth2/clientcredentials"
|
||||
)
|
||||
|
||||
type customTokenSource struct {
|
||||
config *clientcredentials.Config
|
||||
ctx context.Context
|
||||
refreshToken string
|
||||
}
|
||||
|
||||
func (c *customTokenSource) Token() (*oauth2.Token, error) {
|
||||
v := url.Values{}
|
||||
if c.refreshToken != "" {
|
||||
v.Set("grant_type", "refresh_token")
|
||||
v.Set("refresh_token", c.refreshToken)
|
||||
} else {
|
||||
v.Set("grant_type", "client_credentials")
|
||||
}
|
||||
|
||||
v.Set("client_id", c.config.ClientID)
|
||||
v.Set("client_secret", c.config.ClientSecret)
|
||||
|
||||
req, err := http.NewRequest("POST", c.config.TokenURL, strings.NewReader(v.Encode()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
|
||||
resp, err := http.DefaultClient.Do(req.WithContext(c.ctx))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, errors.New("oauth2: cannot fetch token")
|
||||
}
|
||||
|
||||
var tokenResp struct {
|
||||
Code int `json:"code"`
|
||||
Msg string `json:"msg"`
|
||||
Data struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
ExpiresIn int64 `json:"expires_in"`
|
||||
TokenType string `json:"token_type"`
|
||||
Scope string `json:"scope"`
|
||||
RefreshToken string `json:"refresh_token"`
|
||||
} `json:"data"`
|
||||
}
|
||||
|
||||
if err := json.NewDecoder(resp.Body).Decode(&tokenResp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if tokenResp.Code != 1 {
|
||||
return nil, errors.New("oauth2: server response error")
|
||||
}
|
||||
|
||||
c.refreshToken = tokenResp.Data.RefreshToken
|
||||
|
||||
token := &oauth2.Token{
|
||||
AccessToken: tokenResp.Data.AccessToken,
|
||||
TokenType: tokenResp.Data.TokenType,
|
||||
RefreshToken: tokenResp.Data.RefreshToken,
|
||||
Expiry: time.Now().Add(time.Duration(tokenResp.Data.ExpiresIn) * time.Second),
|
||||
}
|
||||
|
||||
return token, nil
|
||||
}
|
||||
|
||||
func (d *FebBox) initializeOAuth2Token(ctx context.Context, oauth2Config *clientcredentials.Config, refreshToken string) {
|
||||
d.oauth2Token = oauth2.ReuseTokenSource(nil, &customTokenSource{
|
||||
config: oauth2Config,
|
||||
ctx: ctx,
|
||||
refreshToken: refreshToken,
|
||||
})
|
||||
}
|
Reference in New Issue
Block a user