diff --git a/Documentation/connectors/google.md b/Documentation/connectors/google.md index 752248736e..8de9a9e7ce 100644 --- a/Documentation/connectors/google.md +++ b/Documentation/connectors/google.md @@ -43,6 +43,16 @@ connectors: # #serviceAccountFilePath: googleAuth.json #adminEmail: super-user@example.com + + # When fetching groups, this field allows to add a regexp to filter the groups + # that will be returned and used. + # This can be useful when the user is registered on a lot of groups because + # he is part of multiple clusters. In this case, usually, the groups are named + # with a pattern and a regexp can be used to filter the groups per cluster, + # allowing to have a smaller group list retrieved for each cluster. + # Default to empty string, and no filtering will be done in this case. + # + # groupsFilter: '^regexp.*' ``` ## Fetching groups from Google diff --git a/connector/google/google.go b/connector/google/google.go index 0e8238514d..72db1e2962 100644 --- a/connector/google/google.go +++ b/connector/google/google.go @@ -7,6 +7,7 @@ import ( "fmt" "io/ioutil" "net/http" + "regexp" "time" "github.com/coreos/go-oidc" @@ -39,6 +40,9 @@ type Config struct { // If this field is nonempty, only users from a listed group will be allowed to log in Groups []string `json:"groups"` + // Optional field to filter groups by regexp + GroupsFilter string `json:"groupsFilter"` + // Optional path to service account json // If nonempty, and groups claim is made, will use authentication from file to // check groups with the admin directory api @@ -73,6 +77,18 @@ func (c *Config) Open(id string, logger log.Logger) (conn connector.Connector, e return nil, fmt.Errorf("could not create directory service: %v", err) } + var groupsFilter *regexp.Regexp + if c.GroupsFilter != "" { + var err error + groupsFilter, err = regexp.Compile(c.GroupsFilter) + if err != nil { + cancel() + return nil, fmt.Errorf("unable to compile the groupsFilter regexp. "+ + "Input string: %q; error: %v", c.GroupsFilter, err, + ) + } + } + clientID := c.ClientID return &googleConnector{ redirectURI: c.RedirectURI, @@ -90,6 +106,7 @@ func (c *Config) Open(id string, logger log.Logger) (conn connector.Connector, e cancel: cancel, hostedDomains: c.HostedDomains, groups: c.Groups, + groupsFilter: groupsFilter, serviceAccountFilePath: c.ServiceAccountFilePath, adminEmail: c.AdminEmail, adminSrv: srv, @@ -109,6 +126,7 @@ type googleConnector struct { logger log.Logger hostedDomains []string groups []string + groupsFilter *regexp.Regexp serviceAccountFilePath string adminEmail string adminSrv *admin.Service @@ -251,8 +269,9 @@ func (c *googleConnector) getGroups(email string) ([]string, error) { } for _, group := range groupsList.Groups { - // TODO (joelspeed): Make desried group key configurable - userGroups = append(userGroups, group.Email) + if c.groupsFilter == nil || c.groupsFilter.MatchString(group.Email) { + userGroups = append(userGroups, group.Email) + } } if groupsList.NextPageToken == "" {