"fmt"
"io/ioutil"
"net/http"
+ "net/url"
"strings"
"time"
"github.com/octo/kraftakt/app"
+ "github.com/octo/retry"
"golang.org/x/oauth2"
oauth2fitbit "golang.org/x/oauth2/fitbit"
"google.golang.org/appengine"
"google.golang.org/appengine/log"
+ "google.golang.org/appengine/urlfetch"
)
func oauthConfig() *oauth2.Config {
return ret, nil
}
+func (c *Client) revokeToken(ctx context.Context) error {
+ tok, err := c.appUser.Token(ctx, "Fitbit")
+ if err != nil {
+ return err
+ }
+
+ httpClient := urlfetch.Client(ctx)
+ httpClient.Transport = retry.NewTransport(httpClient.Transport)
+
+ url := "https://api.fitbit.com/oauth2/revoke?token=" + url.QueryEscape(tok.AccessToken)
+ req, err := http.NewRequest(http.MethodGet, url, nil)
+ if err != nil {
+ return err
+ }
+ req.Header.Set("Authorization", "Basic "+
+ base64.StdEncoding.EncodeToString([]byte(
+ app.Config.FitbitClientID+":"+app.Config.FitbitClientSecret)))
+
+ res, err := httpClient.Do(req)
+ if err != nil {
+ return fmt.Errorf("GET %s: %v", url, err)
+ }
+ defer res.Body.Close()
+
+ if res.StatusCode != http.StatusOK {
+ if data, err := ioutil.ReadAll(res.Body); err == nil {
+ return fmt.Errorf("GET %s: %s", url, data)
+ } else {
+ return fmt.Errorf("GET %s: %s", url, res.Status)
+ }
+ }
+
+ return nil
+}
+
// DeleteToken deletes the Fitbit OAuth2 token.
func (c *Client) DeleteToken(ctx context.Context) error {
+ if err := c.revokeToken(ctx); err != nil {
+ log.Warningf(ctx, "revokeToken() = %v", err)
+ }
+
return c.appUser.DeleteToken(ctx, "Fitbit")
}