@@ -229,38 +229,79 @@ func (p *GoogleProvider) setGroupRestriction(opts options.GoogleOptions) {
229229 }
230230}
231231
232−func getAdminService(opts options.GoogleOptions) *admin.Service {
233− ctx := context.Background()
234− var client *http.Client
232+// https://developers.google.com/admin-sdk/directory/reference/rest/v1/members/hasMember#authorization-scopes
233+var possibleScopesList = [...]string{
234+ admin.AdminDirectoryGroupMemberReadonlyScope,
235+ admin.AdminDirectoryGroupReadonlyScope,
236+ admin.AdminDirectoryGroupMemberScope,
237+ admin.AdminDirectoryGroupScope,
238+}
239+
240+func getOauth2TokenSource(ctx context.Context, opts options.GoogleOptions, scope string) oauth2.TokenSource {
235241 if opts.UseApplicationDefaultCredentials {
236242 ts, err := impersonate.CredentialsTokenSource(ctx, impersonate.CredentialsConfig{
237243 TargetPrincipal: getTargetPrincipal(ctx, opts),
238− Scopes: []string{admin.AdminDirectoryGroupReadonlyScope, admin.AdminDirectoryUserReadonlyScope},
244+ Scopes: []string{scope},
239245 Subject: opts.AdminEmail,
240246 })
241247 if err != nil {
242248 logger.Fatal("failed to fetch application default credentials: ", err)
243249 }
244− client = oauth2.NewClient(ctx, ts)
245− } else {
246− credentialsReader, err := os.Open(opts.ServiceAccountJSON)
247− if err != nil {
248− logger.Fatal("couldn't open Google credentials file: ", err)
249− return nil
250− }
250+ return ts
251+ }
251252
252− data, err := io.ReadAll(credentialsReader)
253− if err != nil {
254− logger.Fatal("can't read Google credentials file:", err)
253+ credentialsReader, err := os.Open(opts.ServiceAccountJSON)
254+ if err != nil {
255+ logger.Fatal("couldn't open Google credentials file: ", err)
256+ }
257+
258+ data, err := io.ReadAll(credentialsReader)
259+ if err != nil {
260+ logger.Fatal("can't read Google credentials file:", err)
261+ }
262+
263+ conf, err := google.JWTConfigFromJSON(data, scope)
264+ if err != nil {
265+ logger.Fatal("can't load Google credentials file:", err)
266+ }
267+
268+ conf.Subject = opts.AdminEmail
269+ return conf.TokenSource(ctx)
270+}
271+
272+func getAdminService(opts options.GoogleOptions) *admin.Service {
273+ ctx := context.Background()
274+ var client *http.Client
275+
276+ for _, scope := range possibleScopesList {
277+
278+ ts := getOauth2TokenSource(ctx, opts, scope)
279+ _, err := ts.Token()
280+
281+ if err == nil {
282+ client = oauth2.NewClient(ctx, ts)
283+ break
255284 }
256285
257− conf, err := google.JWTConfigFromJSON(data, admin.AdminDirectoryUserReadonlyScope, admin.AdminDirectoryGroupReadonlyScope)
258− if err != nil {
259− logger.Fatal("can't load Google credentials file:", err)
286+ if retrieveErr, ok := err.(*oauth2.RetrieveError); ok {
287+ retrieveErrBody := map[string]interface{}{}
288+
289+ if err := json.Unmarshal(retrieveErr.Body, &retrieveErrBody); err != nil {
290+ logger.Fatal("error unmarshalling retrieveErr body:", err)
291+ }
292+
293+ if retrieveErrBody["error"] == "unauthorized_client" && retrieveErrBody["error_description"] == "Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested." {
294+ continue
295+ }
296+
297+ logger.Fatal("error retrieving token:", err)
260298 }
261− conf.Subject = opts.AdminEmail
262− client = conf.Client(ctx)
263299 }
300+
301+ if client == nil {
302+ logger.Fatal("error: google credentials do not have enough permissions to access admin API scope")
303+ }
304+
264305 adminService, err := admin.NewService(ctx, option.WithHTTPClient(client))
265306 if err != nil {
266307 logger.Fatal(err)