Skip to content

Commit

Permalink
auth: walk nested groups
Browse files Browse the repository at this point in the history
  • Loading branch information
jphines committed Jan 24, 2019
1 parent 4bff12f commit 02450d6
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 9 deletions.
6 changes: 3 additions & 3 deletions internal/auth/providers/google.go
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ func (p *GoogleProvider) Redeem(redirectURL, code string) (*sessions.SessionStat

// PopulateMembers is the fill function for the groups cache
func (p *GoogleProvider) PopulateMembers(group string) (groups.MemberSet, error) {
members, err := p.AdminService.GetMembers(group)
members, err := p.AdminService.GetMembers(group, 0)
if err != nil {
return nil, err
}
Expand All @@ -340,7 +340,7 @@ func (p *GoogleProvider) ValidateGroupMembership(email string, allGroups []strin

// if `allGroups` is empty use the groups resource
if len(allGroups) == 0 {
return p.AdminService.GetGroups(email)
return p.AdminService.GetGroups(email, 0)
}

// iterate over the groups, if a set isn't populated only call the GroupsResource once and check all groups
Expand All @@ -362,7 +362,7 @@ func (p *GoogleProvider) ValidateGroupMembership(email string, allGroups []strin
// if a member set was not populated, use the groups resource to get all the groups and filter out the ones that are in `allGroups`
if useGroupsResource {
filtered := []string{}
userGroups, err := p.AdminService.GetGroups(email)
userGroups, err := p.AdminService.GetGroups(email, 0)
if err != nil {
return nil, err
}
Expand Down
30 changes: 26 additions & 4 deletions internal/auth/providers/google_admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ import (

// AdminService wraps calls to provider admin APIs
type AdminService interface {
GetMembers(string) ([]string, error)
GetGroups(string) ([]string, error)
GetMembers(string, int) ([]string, error)
GetGroups(string, int) ([]string, error)
}

// GoogleAdminService is an AdminService for the google provider
Expand Down Expand Up @@ -52,7 +52,7 @@ func getAdminService(adminEmail string, credentialsReader io.Reader) *admin.Serv
}

// GetMembers returns the members of a google group
func (gs *GoogleAdminService) GetMembers(groupName string) ([]string, error) {
func (gs *GoogleAdminService) GetMembers(groupName string, tail int) ([]string, error) {
var members []string
tags := []string{
"provider:google",
Expand Down Expand Up @@ -109,6 +109,17 @@ func (gs *GoogleAdminService) GetMembers(groupName string) ([]string, error) {

for _, member := range r.Members {
members = append(members, member.Email)
if member.Type == "GROUP" {
// this is a nested group, recursively walk down the nested group, we only recurse 2 degrees
if tail >= 2 {
break
}
groupMembers, err := gs.GetMembers(member.Email, tail+1)
if err != nil {
return nil, err
}
members = append(members, groupMembers...)
}
}
if r.NextPageToken == "" {
break
Expand All @@ -119,7 +130,7 @@ func (gs *GoogleAdminService) GetMembers(groupName string) ([]string, error) {
}

// GetGroups gets the groups that a user with a given email address belongs to.
func (gs *GoogleAdminService) GetGroups(email string) ([]string, error) {
func (gs *GoogleAdminService) GetGroups(email string, tail int) ([]string, error) {
var groups []string
tags := []string{
"provider:google",
Expand Down Expand Up @@ -174,6 +185,17 @@ func (gs *GoogleAdminService) GetGroups(email string) ([]string, error) {

for _, group := range r.Groups {
groups = append(groups, group.Email)
// we check if this group is nested and walk up the group structure, only 2 degrees
if tail >= 2 {
break
}

// we recursively walk up the group structure to find super groups
groupsGroup, err := gs.GetGroups(group.Email, tail+1)
if err != nil {
return nil, err
}
groups = append(groups, groupsGroup...)
}
if r.NextPageToken == "" {
break
Expand Down
4 changes: 2 additions & 2 deletions internal/auth/providers/mock_admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ type MockAdminService struct {
}

// GetMembers mocks the GetMembers function
func (ms *MockAdminService) GetMembers(string) ([]string, error) {
func (ms *MockAdminService) GetMembers(string, int) ([]string, error) {
return ms.Members, ms.MembersError
}

// GetGroups mocks the GetGroups function
func (ms *MockAdminService) GetGroups(string) ([]string, error) {
func (ms *MockAdminService) GetGroups(string, int) ([]string, error) {
return ms.Groups, ms.GroupsError
}

0 comments on commit 02450d6

Please sign in to comment.