loginsrv

Unnamed repository; edit this file 'description' to name the repository.
git clone git@jamesshield.xyz:repos/loginsrv.git
Log | Files | Refs | README | LICENSE

google.go (2124B)


      1 package oauth2
      2 
      3 import (
      4 	"encoding/json"
      5 	"fmt"
      6 	"io/ioutil"
      7 	"net/http"
      8 	"strings"
      9 
     10 	"github.com/tarent/loginsrv/model"
     11 )
     12 
     13 
     14 var googleUserinfoEndpoint = "https://www.googleapis.com/oauth2/v3/userinfo"
     15 
     16 func init() {
     17 	RegisterProvider(providerGoogle)
     18 }
     19 
     20 type GoogleUser struct {
     21 	Name               string `json:"name"`
     22 	Email              string `json:"email"`
     23 	EmailVerified      bool   `json:"email_verified"`
     24 	Picture            string `json:"picture"`
     25 	HostedGsuiteDomain string `json:"hd"`
     26 }
     27 
     28 var providerGoogle = Provider{
     29 	Name:          "google",
     30 	AuthURL:       "https://accounts.google.com/o/oauth2/v2/auth",
     31 	TokenURL:      "https://www.googleapis.com/oauth2/v4/token",
     32 	DefaultScopes: "email profile",
     33 	GetUserInfo: func(token TokenInfo) (model.UserInfo, string, error) {
     34 		gu := GoogleUser{}
     35 		url := fmt.Sprintf("%v?access_token=%v", googleUserinfoEndpoint, token.AccessToken)
     36 		resp, err := http.Get(url)
     37 
     38 		if err != nil {
     39 			return model.UserInfo{}, "", err
     40 		}
     41 		defer resp.Body.Close()
     42 
     43 		if !strings.Contains(resp.Header.Get("Content-Type"), "application/json") {
     44 			return model.UserInfo{}, "", fmt.Errorf("wrong content-type on google get user info: %v", resp.Header.Get("Content-Type"))
     45 		}
     46 
     47 		if resp.StatusCode != 200 {
     48 			return model.UserInfo{}, "", fmt.Errorf("got http status %v on google get user info", resp.StatusCode)
     49 		}
     50 
     51 		b, err := ioutil.ReadAll(resp.Body)
     52 		if err != nil {
     53 			return model.UserInfo{}, "", fmt.Errorf("error reading google get user info: %v", err)
     54 		}
     55 
     56 		err = json.Unmarshal(b, &gu)
     57 		if err != nil {
     58 			return model.UserInfo{}, "", fmt.Errorf("error parsing google get user info: %v", err)
     59 		}
     60 
     61 		if len(gu.Email) == 0 {
     62 			return model.UserInfo{}, "", fmt.Errorf("invalid google response: no email address returned.")
     63 		}
     64 
     65 		if !gu.EmailVerified {
     66 			return model.UserInfo{}, "", fmt.Errorf("invalid google response: users email address not verified by google.")
     67 		}
     68 
     69 		return model.UserInfo{
     70 			Sub:     gu.Email,
     71 			Picture: gu.Picture,
     72 			Name:    gu.Name,
     73 			Email:   gu.Email,
     74 			Origin:  "google",
     75 			Domain:  gu.HostedGsuiteDomain,
     76 		}, string(b), nil
     77 	},
     78 }