Skip to content

Instantly share code, notes, and snippets.

@patrick91
Forked from agtorre/config.go
Last active September 15, 2018 11:43
Show Gist options
  • Save patrick91/f1d725a985b552261448 to your computer and use it in GitHub Desktop.
Save patrick91/f1d725a985b552261448 to your computer and use it in GitHub Desktop.
Store OAuth2 Token Using Datastore
// 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