Skip to content

Commit

Permalink
[Patch] Add Google's FetchUser logic with UserID.
Browse files Browse the repository at this point in the history
  • Loading branch information
althenlimzixuan committed Nov 21, 2024
1 parent 876e71a commit 9759535
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 9 deletions.
30 changes: 28 additions & 2 deletions gothic/gothic.go
Original file line number Diff line number Diff line change
Expand Up @@ -366,9 +366,35 @@ func updateSessionValue(session *sessions.Session, key, value string) error {
return nil
}

func FetchUserInfoWithToken(token string) (goth.User, error) {
func FetchUserInfoWithToken(token string, providerName string, sessionValues interface{}) (goth.User, *goth.Session, error) {

result := goth.User{}

return result, nil
if token == "" {
return result, nil, fmt.Errorf("cannot get user information without accessToken")
}

provider, err := goth.GetProvider(providerName)
if err != nil {
return result, nil, err
}

session, err := provider.CreateSession(sessionValues)
if err != nil {
return result, nil, err
}

sess, err := provider.UnmarshalSession(session.Marshal())

if err != nil {
return result, nil, err
}

user, err := provider.FetchUser(sess)

if err != nil {
return result, nil, err
}

return user, &session, nil
}
34 changes: 28 additions & 6 deletions providers/google/google.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@ import (
"golang.org/x/oauth2"
)

const endpointProfile string = "https://www.googleapis.com/oauth2/v2/userinfo"
const (
endpointProfile string = "https://www.googleapis.com/oauth2/v2/userinfo"
authURL string = "https://accounts.google.com/o/oauth2/auth?access_type=offline"
tokenURL string = "https://accounts.google.com/o/oauth2/token"
idTokenProfile string = "https://www.googleapis.com/oauth2/v3/tokeninfo"
)

// New creates a new Google provider, and sets up important connection details.
// You should always call `google.New` to get a new Provider. Never try to create
Expand Down Expand Up @@ -96,16 +101,34 @@ func (p *Provider) FetchUser(session goth.Session) (goth.User, error) {
IDToken: sess.IDToken,
}

if user.AccessToken == "" {
if user.AccessToken == "" && user.IDToken == "" {
// Data is not yet retrieved, since accessToken is still empty.
return user, fmt.Errorf("%s cannot get user information without accessToken", p.providerName)
return user, fmt.Errorf("%s cannot get user information without accessToken AND idToken", p.providerName)
}

var response *http.Response
var err error
// retrievedViaIDToken := false

if user.IDToken != "" {
// retrievedViaIDToken = true
response, err = p.Client().Get(idTokenProfile + "?id_token=" + url.QueryEscape(sess.IDToken))
if response.StatusCode == http.StatusBadRequest && len(sess.AccessToken) > 0 {
response, err = p.Client().Get(endpointProfile + "?access_token=" + url.QueryEscape(sess.AccessToken))
// retrievedViaIDToken = false
}

} else {
response, err = p.Client().Get(endpointProfile + "?access_token=" + url.QueryEscape(sess.AccessToken))
}

if response != nil {
defer response.Body.Close()
}

response, err := p.Client().Get(endpointProfile + "?access_token=" + url.QueryEscape(sess.AccessToken))
if err != nil {
return user, err
}
defer response.Body.Close()

if response.StatusCode != http.StatusOK {
return user, fmt.Errorf("%s responded with a %d trying to fetch user information", p.providerName, response.StatusCode)
Expand Down Expand Up @@ -212,6 +235,5 @@ func (p *Provider) SetAccessType(at string) {
}

func (p *Provider) FetchUserWithToken(token string) (goth.User, error) {
//TODO: Implement this
return goth.User{}, errors.New("not implemented")
}
21 changes: 20 additions & 1 deletion providers/google/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,24 @@ func (p *Provider) UnmarshalSession(data string) (goth.Session, error) {
}

func (p *Provider) CreateSession(sessionValue interface{}) (goth.Session, error) {
return &Session{}, errors.New("not implemented")
// First retrieve following keys with it's values from sessionValue
// - accessToken
// - expiresIn
// - clientID

// Then create a new session with the retrieved values
sessStruct := sessionValue.(map[string]interface{})

accessToken := sessStruct["accessToken"].(string)
expiresIn := sessStruct["expiresIn"].(time.Time)

session := &Session{
AccessToken: accessToken,
IDToken: accessToken,
ExpiresAt: expiresIn,
}

// ClientID = clientID

return session, nil
}

0 comments on commit 9759535

Please sign in to comment.