-
-
Save patrick91/f1d725a985b552261448 to your computer and use it in GitHub Desktop.
Store OAuth2 Token Using Datastore
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Config is a custom oauth2 config that is used to store the token | |
// in the datastore | |
type Config struct { | |
*oauth2.Config | |
} | |
// StoreToken is called when exchanging the token and saves the token | |
// in the datastore | |
func (c *Config) StoreToken(ctx context.Context, token *oauth2.Token) error { | |
log.Infof(ctx, "storing the token") | |
key := datastore.NewKey(ctx, "Tokens", "fitbit", 0, nil) | |
_, err := datastore.Put(ctx, key, token) | |
return err | |
} | |
// Exchange is a wrapper around oauth2.config.Exchange and stores the Token | |
// in the datastore | |
func (c *Config) Exchange(ctx context.Context, code string) (*oauth2.Token, error) { | |
token, err := c.Config.Exchange(ctx, code) | |
if err != nil { | |
return nil, err | |
} | |
if err := c.StoreToken(ctx, token); err != nil { | |
return nil, err | |
} | |
return token, nil | |
} | |
// Client creates a new client using our custom TokenSource | |
func (c *Config) Client(ctx context.Context, t *oauth2.Token) *http.Client { | |
return oauth2.NewClient(ctx, c.TokenSource(ctx, t)) | |
} | |
// TokenSource uses uses our DatastoreTokenSource as the source token | |
func (c *Config) TokenSource(ctx context.Context, t *oauth2.Token) oauth2.TokenSource { | |
rts := &DatastoreTokenSource{ | |
source: c.Config.TokenSource(ctx, t), | |
config: c, | |
ctx: ctx, | |
} | |
return oauth2.ReuseTokenSource(t, rts) | |
} | |
// DatastoreTokenSource is our custom TokenSource | |
type DatastoreTokenSource struct { | |
config *Config | |
source oauth2.TokenSource | |
ctx context.Context | |
} | |
// Token saves the token in the datastore when it is updated | |
func (t *DatastoreTokenSource) Token() (*oauth2.Token, error) { | |
token, err := t.source.Token() | |
if err != nil { | |
return nil, err | |
} | |
if err := t.config.StoreToken(t.ctx, token); err != nil { | |
return nil, err | |
} | |
return token, nil | |
} | |
func getFitbitConf(ctx context.Context) (*Config, error) { | |
var data Settings | |
err := GetSettings(ctx, &data) | |
if err != nil { | |
return nil, err | |
} | |
var fitbitConf = &Config{ | |
Config: &oauth2.Config{ | |
ClientID: data.FitbitClientID, | |
ClientSecret: data.FitbitClientSecret, | |
Scopes: []string{"activity", "weight", "profile"}, | |
Endpoint: oauth2.Endpoint{ | |
AuthURL: "https://www.fitbit.com/oauth2/authorize", | |
TokenURL: "https://api.fitbit.com/oauth2/token", | |
}, | |
}, | |
} | |
return fitbitConf, nil | |
} | |
func getToken(ctx context.Context, data *oauth2.Token) error { | |
key := datastore.NewKey(ctx, "Tokens", "fitbit", 0, nil) | |
err := datastore.Get(ctx, key, data) | |
return err | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment