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