Merge "services/identity: Force the OAuth approval prompt when seeking blessings."
diff --git a/services/identity/internal/oauth/googleoauth.go b/services/identity/internal/oauth/googleoauth.go
index ca8303f..c8898cf 100644
--- a/services/identity/internal/oauth/googleoauth.go
+++ b/services/identity/internal/oauth/googleoauth.go
@@ -41,8 +41,12 @@
}, nil
}
-func (g *googleOAuth) AuthURL(redirectUrl, state string) string {
- return g.oauthConfig(redirectUrl).AuthCodeURL(state)
+func (g *googleOAuth) AuthURL(redirectUrl, state string, approval AuthURLApproval) string {
+ var opts []oauth2.AuthCodeOption
+ if approval == ExplicitApproval {
+ opts = append(opts, oauth2.ApprovalForce)
+ }
+ return g.oauthConfig(redirectUrl).AuthCodeURL(state, opts...)
}
// ExchangeAuthCodeForEmail exchanges the authorization code (which must
diff --git a/services/identity/internal/oauth/handler.go b/services/identity/internal/oauth/handler.go
index 6dddbf5..bea1fae 100644
--- a/services/identity/internal/oauth/handler.go
+++ b/services/identity/internal/oauth/handler.go
@@ -146,7 +146,7 @@
util.HTTPServerError(w, fmt.Errorf("failed to create new token: %v", err))
return
}
- http.Redirect(w, r, h.args.OAuthProvider.AuthURL(redirectURL(h.args.Addr, listBlessingsCallbackRoute), csrf), http.StatusFound)
+ http.Redirect(w, r, h.args.OAuthProvider.AuthURL(redirectURL(h.args.Addr, listBlessingsCallbackRoute), csrf, ReuseApproval), http.StatusFound)
}
func (h *handler) listBlessingsCallback(w http.ResponseWriter, r *http.Request) {
@@ -344,7 +344,7 @@
util.HTTPServerError(w, fmt.Errorf("failed to create new token: %v", err))
return
}
- http.Redirect(w, r, h.args.OAuthProvider.AuthURL(redirectURL(h.args.Addr, addCaveatsRoute), outputMacaroon), http.StatusFound)
+ http.Redirect(w, r, h.args.OAuthProvider.AuthURL(redirectURL(h.args.Addr, addCaveatsRoute), outputMacaroon, ExplicitApproval), http.StatusFound)
}
type addCaveatsMacaroon struct {
diff --git a/services/identity/internal/oauth/mockoauth.go b/services/identity/internal/oauth/mockoauth.go
index dd705be..c122af7 100644
--- a/services/identity/internal/oauth/mockoauth.go
+++ b/services/identity/internal/oauth/mockoauth.go
@@ -16,7 +16,7 @@
return &mockOAuth{}
}
-func (m *mockOAuth) AuthURL(redirectUrl string, state string) string {
+func (m *mockOAuth) AuthURL(redirectUrl string, state string, _ AuthURLApproval) string {
return redirectUrl + "?state=" + state
}
diff --git a/services/identity/internal/oauth/oauth_provider.go b/services/identity/internal/oauth/oauth_provider.go
index 3597810..8ba6239 100644
--- a/services/identity/internal/oauth/oauth_provider.go
+++ b/services/identity/internal/oauth/oauth_provider.go
@@ -12,11 +12,19 @@
ClientID string
}
+// Option to OAuthProvider.AuthURL controlling whether previously provided user consent can be re-used.
+type AuthURLApproval bool
+
+const (
+ ExplicitApproval AuthURLApproval = false // Require explicit user consent.
+ ReuseApproval AuthURLApproval = true // Reuse a previous user consent if possible.
+)
+
// OAuthProvider authenticates users to the identity server via the OAuth2 Web Server flow.
type OAuthProvider interface {
// AuthURL is the URL the user must visit in order to authenticate with the OAuthProvider.
// After authentication, the user will be re-directed to redirectURL with the provided state.
- AuthURL(redirectUrl string, state string) (url string)
+ AuthURL(redirectUrl string, state string, approval AuthURLApproval) (url string)
// ExchangeAuthCodeForEmail exchanges the provided authCode for the email of the
// authenticated user on behalf of the token has been issued.
ExchangeAuthCodeForEmail(authCode string, url string) (email string, err error)