Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Google provider: use groups.list with userKey param for group check #6

Merged
merged 2 commits into from
Nov 26, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 19 additions & 53 deletions providers/google.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import (
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
"google.golang.org/api/admin/directory/v1"
"google.golang.org/api/googleapi"
)

type GoogleProvider struct {
Expand Down Expand Up @@ -180,67 +179,34 @@ func getAdminService(adminEmail string, credentialsReader io.Reader) *admin.Serv
}

func userInGroup(service *admin.Service, groups []string, email string) bool {
user, err := fetchUser(service, email)
if err != nil {
log.Printf("error fetching user: %v", err)
return false
}
id := user.Id
custID := user.CustomerId

for _, group := range groups {
members, err := fetchGroupMembers(service, group)
if err != nil {
if err, ok := err.(*googleapi.Error); ok && err.Code == 404 {
log.Printf("error fetching members for group %s: group does not exist", group)
} else {
log.Printf("error fetching group members: %v", err)
return false
}
}

for _, member := range members {
switch member.Type {
case "CUSTOMER":
if member.Id == custID {
return true
}
case "USER":
if member.Id == id {
return true
}
}
}
}
return false
}

func fetchUser(service *admin.Service, email string) (*admin.User, error) {
user, err := service.Users.Get(email).Do()
return user, err
}

func fetchGroupMembers(service *admin.Service, group string) ([]*admin.Member, error) {
members := []*admin.Member{}
pageToken := ""
for {
req := service.Members.List(group)
// limit to 10 pages/requests
for i := 0; i < 10; i++ {
req := service.Groups.List().UserKey(email)
if pageToken != "" {
req.PageToken(pageToken)
}
r, err := req.Do()
resp, err := req.Do()
if err != nil {
return nil, err
log.Printf("Error calling service.Groups.List().userKey(%s)", email)
return false
}
for _, member := range r.Members {
members = append(members, member)
for _, group := range resp.Groups {
for _, allowedgroup := range groups {
if group.Email == allowedgroup {
log.Printf("%s is a member of %s, authorized", email, allowedgroup)
return true
}
}
}
if r.NextPageToken == "" {
break
if resp.NextPageToken == "" {
log.Printf("%s not found in any allowed groups", email)
return false
}
pageToken = r.NextPageToken
pageToken = resp.NextPageToken
}
return members, nil
log.Printf("WARNING: %s has more than 10 pages of groups", email)
return false
}

// ValidateGroup validates that the provided email exists in the configured Google
Expand Down