@@ -27,11 +27,14 @@ type GoogleProvider struct {
2727 *ProviderData
2828
2929 RedeemRefreshURL *url.URL
30+
3031 // GroupValidator is a function that determines if the user in the passed
3132 // session is a member of any of the configured Google groups.
32− GroupValidator func(*sessions.SessionState, bool) bool
33−
34− allowedGroups map[string]struct{}
33+ //
34+ // This hits the Google API for each group, so it is called on Redeem &
35+ // Refresh. `Authorize` uses the results of this saved in `session.Groups`
36+ // Since it is called on every request.
37+ GroupValidator func(*sessions.SessionState) bool
3538}
3639
3740var _ Provider = (*GoogleProvider)(nil)
@@ -89,7 +92,7 @@ func NewGoogleProvider(p *ProviderData) *GoogleProvider {
8992 ProviderData: p,
9093 // Set a default GroupValidator to just always return valid (true), it will
9194 // be overwritten if we configured a Google group restriction.
92− GroupValidator: func(*sessions.SessionState, bool) bool {
95+ GroupValidator: func(*sessions.SessionState) bool {
9396 return true
9497 },
9598 }
@@ -172,45 +175,27 @@ func (p *GoogleProvider) Redeem(ctx context.Context, redirectURL, code string) (
172175 Email: c.Email,
173176 User: c.Subject,
174177 }
175− p.GroupValidator(s, true)
178+ p.GroupValidator(s)
176179
177180 return s, nil
178181}
179182
180−func (p *GoogleProvider) Authorize(ctx context.Context, s *sessions.SessionState) (bool, error) {
181− return p.GroupValidator(s, false), nil
182−}
183−
184183// SetGroupRestriction configures the GoogleProvider to restrict access to the
185184// specified group(s). AdminEmail has to be an administrative email on the domain that is
186185// checked. CredentialsFile is the path to a json file containing a Google service
187186// account credentials.
188187func (p *GoogleProvider) SetGroupRestriction(groups []string, adminEmail string, credentialsReader io.Reader) {
189188 adminService := getAdminService(adminEmail, credentialsReader)
190− for _, group := range groups {
191− p.allowedGroups[group] = struct{}{}
192− }
193−
194− p.GroupValidator = func(s *sessions.SessionState, sync bool) bool {
195− if sync {
196− // Reset our saved Groups in case membership changed
197− s.Groups = make([]string, 0, len(groups))
198− for _, group := range groups {
199− if userInGroup(adminService, group, s.Email) {
200− s.Groups = append(s.Groups, group)
201− }
202− }
203− return len(s.Groups) > 0
204− }
205−
206− // Don't resync with Google, handles when OAuth2-Proxy settings
207− // alter allowed groups but existing sessions are still valid
208− for _, group := range s.Groups {
209− if _, ok := p.allowedGroups[group]; ok {
210− return true
189+ p.GroupValidator = func(s *sessions.SessionState) bool {
190+ // Reset our saved Groups in case membership changed
191+ // This is used by `Authorize` on every request
192+ s.Groups = make([]string, 0, len(groups))
193+ for _, group := range groups {
194+ if userInGroup(adminService, group, s.Email) {
195+ s.Groups = append(s.Groups, group)
211196 }
212197 }
213− return false
198+ return len(s.Groups) > 0
214199 }
215200}
216201
@@ -282,7 +267,7 @@ func (p *GoogleProvider) RefreshSessionIfNeeded(ctx context.Context, s *sessions
282267 }
283268
284269 // re-check that the user is in the proper google group(s)
285− if !p.GroupValidator(s, true) {
270+ if !p.GroupValidator(s) {
286271 return false, fmt.Errorf("%s is no longer in the group(s)", s.Email)
287272 }
288273