|
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, |
|
}) |
|
} |
|
|