From eacba4ec7da203a6f19d5f7f118c7dbf961249dd Mon Sep 17 00:00:00 2001
From: Gabor Lekeny <gabor.lekeny@gmail.com>
Date: Tue, 5 Mar 2019 15:07:10 +0100
Subject: [PATCH] Add id_token refresh to Google provider (#83)

---
 CHANGELOG.md        | 1 +
 providers/google.go | 9 ++++++---
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index c640f1c7..0805a6b9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,7 @@
 
 - [#68](https://github.com/pusher/oauth2_proxy/pull/68) forward X-Auth-Access-Token header (@davidholsgrove)
 - [#41](https://github.com/pusher/oauth2_proxy/pull/41) Added option to manually specify OIDC endpoints instead of relying on discovery
+- [#83](https://github.com/pusher/oauth2_proxy/pull/83) Add `id_token` refresh to Google provider (@leki75)
 
 # v3.1.0
 
diff --git a/providers/google.go b/providers/google.go
index feea36f0..415891c7 100644
--- a/providers/google.go
+++ b/providers/google.go
@@ -16,7 +16,7 @@ import (
 
 	"golang.org/x/oauth2"
 	"golang.org/x/oauth2/google"
-	"google.golang.org/api/admin/directory/v1"
+	admin "google.golang.org/api/admin/directory/v1"
 	"google.golang.org/api/googleapi"
 )
 
@@ -260,7 +260,7 @@ func (p *GoogleProvider) RefreshSessionIfNeeded(s *SessionState) (bool, error) {
 		return false, nil
 	}
 
-	newToken, duration, err := p.redeemRefreshToken(s.RefreshToken)
+	newToken, newIDToken, duration, err := p.redeemRefreshToken(s.RefreshToken)
 	if err != nil {
 		return false, err
 	}
@@ -272,12 +272,13 @@ func (p *GoogleProvider) RefreshSessionIfNeeded(s *SessionState) (bool, error) {
 
 	origExpiration := s.ExpiresOn
 	s.AccessToken = newToken
+	s.IDToken = newIDToken
 	s.ExpiresOn = time.Now().Add(duration).Truncate(time.Second)
 	log.Printf("refreshed access token %s (expired on %s)", s, origExpiration)
 	return true, nil
 }
 
-func (p *GoogleProvider) redeemRefreshToken(refreshToken string) (token string, expires time.Duration, err error) {
+func (p *GoogleProvider) redeemRefreshToken(refreshToken string) (token string, idToken string, expires time.Duration, err error) {
 	// https://developers.google.com/identity/protocols/OAuth2WebServer#refresh
 	params := url.Values{}
 	params.Add("client_id", p.ClientID)
@@ -310,12 +311,14 @@ func (p *GoogleProvider) redeemRefreshToken(refreshToken string) (token string,
 	var data struct {
 		AccessToken string `json:"access_token"`
 		ExpiresIn   int64  `json:"expires_in"`
+		IDToken     string `json:"id_token"`
 	}
 	err = json.Unmarshal(body, &data)
 	if err != nil {
 		return
 	}
 	token = data.AccessToken
+	idToken = data.IDToken
 	expires = time.Duration(data.ExpiresIn) * time.Second
 	return
 }