@@ -71,7 +71,7 @@ func (c *Config) Open(id string, logger log.Logger) (conn connector.Connector, e
71
71
scopes = append (scopes , "profile" , "email" )
72
72
}
73
73
74
- srv , err := createDirectoryService (c .ServiceAccountFilePath , c .AdminEmail , logger )
74
+ srv , err := createDirectoryService (c .ServiceAccountFilePath , c .AdminEmail )
75
75
if err != nil {
76
76
cancel ()
77
77
return nil , fmt .Errorf ("could not create directory service: %v" , err )
@@ -220,7 +220,7 @@ func (c *googleConnector) createIdentity(ctx context.Context, identity connector
220
220
var groups []string
221
221
if s .Groups && c .adminSrv != nil {
222
222
checkedGroups := make (map [string ]struct {})
223
- groups , err = getGroups ( c . getGroupsList , claims .Email , c .fetchTransitiveGroupMembership , checkedGroups )
223
+ groups , err = c . getGroups ( claims .Email , c .fetchTransitiveGroupMembership , checkedGroups )
224
224
if err != nil {
225
225
return identity , fmt .Errorf ("google: could not retrieve groups: %v" , err )
226
226
}
@@ -244,22 +244,15 @@ func (c *googleConnector) createIdentity(ctx context.Context, identity connector
244
244
return identity , nil
245
245
}
246
246
247
- // getGroupsList returns a list of Groups from google
248
- func (c * googleConnector ) getGroupsList (email string , nextPageToken string ) (* admin.Groups , error ) {
249
- groupsList , err := c .adminSrv .Groups .List ().
250
- UserKey (email ).PageToken (nextPageToken ).Do ()
251
- return groupsList , err
252
- }
253
-
254
247
// getGroups creates a connection to the admin directory service and lists
255
248
// all groups the user is a member of
256
- // to test functionality, first parameter is the function you want to run to fetch groups
257
- func getGroups (getGroupsListFunc func (string , string ) (* admin.Groups , error ), email string , fetchTransitiveGroupMembership bool , checkedGroups map [string ]struct {}) ([]string , error ) {
249
+ func (c * googleConnector ) getGroups (email string , fetchTransitiveGroupMembership bool , checkedGroups map [string ]struct {}) ([]string , error ) {
258
250
var userGroups []string
259
251
var err error
260
252
groupsList := & admin.Groups {}
261
253
for {
262
- groupsList , err = getGroupsListFunc (email , groupsList .NextPageToken )
254
+ groupsList , err = c .adminSrv .Groups .List ().
255
+ UserKey (email ).PageToken (groupsList .NextPageToken ).Do ()
263
256
if err != nil {
264
257
return nil , fmt .Errorf ("could not list groups: %v" , err )
265
258
}
@@ -278,7 +271,7 @@ func getGroups(getGroupsListFunc func(string, string) (*admin.Groups, error), em
278
271
}
279
272
280
273
// getGroups takes a user's email/alias as well as a group's email/alias
281
- transitiveGroups , err := getGroups (getGroupsListFunc , group .Email , fetchTransitiveGroupMembership , checkedGroups )
274
+ transitiveGroups , err := c . getGroups (group .Email , fetchTransitiveGroupMembership , checkedGroups )
282
275
if err != nil {
283
276
return nil , fmt .Errorf ("could not list transitive groups: %v" , err )
284
277
}
@@ -294,35 +287,35 @@ func getGroups(getGroupsListFunc func(string, string) (*admin.Groups, error), em
294
287
return userGroups , nil
295
288
}
296
289
297
- // createDirectoryService sets up super user impersonation and creates an admin client for calling
298
- // the google admin api. If no serviceAccountFilePath is defined, the application default credential
299
- // is used.
300
- func createDirectoryService (serviceAccountFilePath , email string , logger log. Logger ) (* admin.Service , error ) {
301
- if email == "" {
302
- return nil , fmt . Errorf ( "directory service requires adminEmail" )
290
+ // createDirectoryService loads a google service account credentials file,
291
+ // sets up super user impersonation and creates an admin client for calling
292
+ // the google admin api
293
+ func createDirectoryService (serviceAccountFilePath string , email string ) (* admin.Service , error ) {
294
+ if serviceAccountFilePath == "" && email == "" {
295
+ return nil , nil
303
296
}
304
-
305
- var jsonCredentials []byte
306
- var err error
307
-
308
- ctx := context .Background ()
309
- if serviceAccountFilePath == "" {
310
- logger .Warn ("the application default credential is used since the service account file path is not used" )
311
- credential , err := google .FindDefaultCredentials (ctx )
312
- if err != nil {
313
- return nil , fmt .Errorf ("failed to fetch application default credentials: %w" , err )
314
- }
315
- jsonCredentials = credential .JSON
316
- } else {
317
- jsonCredentials , err = os .ReadFile (serviceAccountFilePath )
318
- if err != nil {
319
- return nil , fmt .Errorf ("error reading credentials from file: %v" , err )
320
- }
297
+ if serviceAccountFilePath == "" || email == "" {
298
+ return nil , fmt .Errorf ("directory service requires both serviceAccountFilePath and adminEmail" )
299
+ }
300
+ jsonCredentials , err := os .ReadFile (serviceAccountFilePath )
301
+ if err != nil {
302
+ return nil , fmt .Errorf ("error reading credentials from file: %v" , err )
321
303
}
304
+
322
305
config , err := google .JWTConfigFromJSON (jsonCredentials , admin .AdminDirectoryGroupReadonlyScope )
323
306
if err != nil {
324
- return nil , fmt .Errorf ("unable to parse credentials to config: %v" , err )
307
+ return nil , fmt .Errorf ("unable to parse client secret file to config: %v" , err )
325
308
}
309
+
310
+ // Impersonate an admin. This is mandatory for the admin APIs.
326
311
config .Subject = email
327
- return admin .NewService (ctx , option .WithHTTPClient (config .Client (ctx )))
312
+
313
+ ctx := context .Background ()
314
+ client := config .Client (ctx )
315
+
316
+ srv , err := admin .NewService (ctx , option .WithHTTPClient (client ))
317
+ if err != nil {
318
+ return nil , fmt .Errorf ("unable to create directory service %v" , err )
319
+ }
320
+ return srv , nil
328
321
}
0 commit comments