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