github.com/volatiletech/authboss@v2.4.1+incompatible/oauth2/providers.go (about)

     1  package oauth2
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"io/ioutil"
     7  	"net/http"
     8  
     9  	"github.com/pkg/errors"
    10  	"golang.org/x/oauth2"
    11  )
    12  
    13  // Constants for returning in the FindUserDetails call
    14  const (
    15  	OAuth2UID   = "uid"
    16  	OAuth2Email = "email"
    17  	OAuth2Name  = "name"
    18  )
    19  
    20  const (
    21  	googleInfoEndpoint   = `https://www.googleapis.com/userinfo/v2/me`
    22  	facebookInfoEndpoint = `https://graph.facebook.com/me?fields=name,email`
    23  )
    24  
    25  type googleMeResponse struct {
    26  	ID    string `json:"id"`
    27  	Email string `json:"email"`
    28  }
    29  
    30  // testing
    31  var clientGet = (*http.Client).Get
    32  
    33  // GoogleUserDetails can be used as a FindUserDetails function
    34  // for an authboss.OAuth2Provider
    35  func GoogleUserDetails(ctx context.Context, cfg oauth2.Config, token *oauth2.Token) (map[string]string, error) {
    36  	client := cfg.Client(ctx, token)
    37  	resp, err := clientGet(client, googleInfoEndpoint)
    38  	if err != nil {
    39  		return nil, err
    40  	}
    41  
    42  	defer resp.Body.Close()
    43  	byt, err := ioutil.ReadAll(resp.Body)
    44  	if err != nil {
    45  		return nil, errors.Wrap(err, "failed to read body from google oauth2 endpoint")
    46  	}
    47  
    48  	var response googleMeResponse
    49  	if err = json.Unmarshal(byt, &response); err != nil {
    50  		return nil, err
    51  	}
    52  
    53  	return map[string]string{
    54  		OAuth2UID:   response.ID,
    55  		OAuth2Email: response.Email,
    56  	}, nil
    57  }
    58  
    59  type facebookMeResponse struct {
    60  	ID    string `json:"id"`
    61  	Email string `json:"email"`
    62  	Name  string `json:"name"`
    63  }
    64  
    65  // FacebookUserDetails can be used as a FindUserDetails function
    66  // for an authboss.OAuth2Provider
    67  func FacebookUserDetails(ctx context.Context, cfg oauth2.Config, token *oauth2.Token) (map[string]string, error) {
    68  	client := cfg.Client(ctx, token)
    69  	resp, err := clientGet(client, facebookInfoEndpoint)
    70  	if err != nil {
    71  		return nil, err
    72  	}
    73  
    74  	defer resp.Body.Close()
    75  	byt, err := ioutil.ReadAll(resp.Body)
    76  	if err != nil {
    77  		return nil, errors.Wrap(err, "failed to read body from facebook oauth2 endpoint")
    78  	}
    79  
    80  	var response facebookMeResponse
    81  	if err = json.Unmarshal(byt, &response); err != nil {
    82  		return nil, errors.Wrap(err, "failed to parse json from facebook oauth2 endpoint")
    83  	}
    84  
    85  	return map[string]string{
    86  		OAuth2UID:   response.ID,
    87  		OAuth2Email: response.Email,
    88  		OAuth2Name:  response.Name,
    89  	}, nil
    90  }