package goog import ( "context" "encoding/json" "fmt" "io/ioutil" "net/http" "golang.org/x/oauth2" ) var ( ProfileURL = "https://www.googleapis.com/oauth2/v3/userinfo" ProfileKeyFmt = "goog:%s" ) // GoogleProfile auth'd user profile // ProfileId, Email, Name, PictureURL type GoogleProfile struct { ProfileID string `json:"sub"` Email string `json:"email"` Name string `json:"name"` PictureURL string `json:"picture"` } // ProfileKeys conform to ProfileKeys func (gp *GoogleProfile) ProfileKeyValues() (string, []string) { return fmt.Sprintf(ProfileKeyFmt, gp.Email), []string{ "profile_id", gp.ProfileID, "email", gp.Email, "name", gp.Name, "picture_url", gp.PictureURL, } } type Servicer interface { Config() *oauth2.Config Profile(client *http.Client) (*GoogleProfile, *oauth2.Token, error) UserClient(ctx context.Context, token *oauth2.Token) *http.Client } // NewService container for interacting with Google func NewService(o *oauth2.Config) Servicer { return &Goog{ o, } } type Goog struct { oauthConfig *oauth2.Config } func (g *Goog) Config() *oauth2.Config { return g.oauthConfig } // UserCient just calls oauth2.Client func (g *Goog) UserClient(ctx context.Context, token *oauth2.Token) *http.Client { return g.oauthConfig.Client(ctx, token) } // Profile get profile from google func (g *Goog) Profile(client *http.Client) (*GoogleProfile, *oauth2.Token, error) { client.Get(ProfileURL) resp, err := client.Get(ProfileURL) if err != nil { return &GoogleProfile{}, &oauth2.Token{}, err } defer resp.Body.Close() data, err := ioutil.ReadAll(resp.Body) if err != nil { return &GoogleProfile{}, &oauth2.Token{}, err } // Google Profile gp := &GoogleProfile{} err = json.Unmarshal(data, gp) if err != nil { return &GoogleProfile{}, &oauth2.Token{}, err } // Token token := &oauth2.Token{} err = json.Unmarshal(data, token) if err != nil { return &GoogleProfile{}, &oauth2.Token{}, err } return gp, token, nil }