From a38e21589172ff6e6e5a042244ce38dc26ff3f93 Mon Sep 17 00:00:00 2001
From: Nandor Kracser <bonifaido@gmail.com>
Date: Tue, 3 Dec 2019 16:27:07 +0100
Subject: [PATCH] connector/google: support group whitelisting

Signed-off-by: Nandor Kracser <bonifaido@gmail.com>
---
 Documentation/connectors/google.md |  7 +++++++
 connector/google/google.go         | 16 +++++++++++++++-
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/Documentation/connectors/google.md b/Documentation/connectors/google.md
index 1bfe321c..75224873 100644
--- a/Documentation/connectors/google.md
+++ b/Documentation/connectors/google.md
@@ -29,6 +29,13 @@ connectors:
     # hostedDomains:
     #  - example.com
 
+    # The Google connector supports whitelisting allowed groups when using G Suite
+    # (Google Apps). The following field can be set to a list of groups
+    # that can log in:
+    #
+    # groups:
+    #  - admins@example.com
+
     # Google does not support the OpenID Connect groups claim and only supports
     # fetching a user's group membership with a service account.
     # This service account requires an authentication JSON file and the email
diff --git a/connector/google/google.go b/connector/google/google.go
index d86abbcb..84e5580d 100644
--- a/connector/google/google.go
+++ b/connector/google/google.go
@@ -13,9 +13,10 @@ import (
 	"golang.org/x/oauth2"
 
 	"github.com/dexidp/dex/connector"
+	pkg_groups "github.com/dexidp/dex/pkg/groups"
 	"github.com/dexidp/dex/pkg/log"
 	"golang.org/x/oauth2/google"
-	"google.golang.org/api/admin/directory/v1"
+	admin "google.golang.org/api/admin/directory/v1"
 )
 
 const (
@@ -34,6 +35,10 @@ type Config struct {
 	// If this field is nonempty, only users from a listed domain will be allowed to log in
 	HostedDomains []string `json:"hostedDomains"`
 
+	// Optional list of whitelisted groups
+	// If this field is nonempty, only users from a listed group will be allowed to log in
+	Groups []string `json:"groups"`
+
 	// 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
@@ -84,6 +89,7 @@ func (c *Config) Open(id string, logger log.Logger) (conn connector.Connector, e
 		logger:                 logger,
 		cancel:                 cancel,
 		hostedDomains:          c.HostedDomains,
+		groups:                 c.Groups,
 		serviceAccountFilePath: c.ServiceAccountFilePath,
 		adminEmail:             c.AdminEmail,
 		adminSrv:               srv,
@@ -103,6 +109,7 @@ type googleConnector struct {
 	cancel                 context.CancelFunc
 	logger                 log.Logger
 	hostedDomains          []string
+	groups                 []string
 	serviceAccountFilePath string
 	adminEmail             string
 	adminSrv               *admin.Service
@@ -211,6 +218,13 @@ func (c *googleConnector) createIdentity(ctx context.Context, identity connector
 		if err != nil {
 			return identity, fmt.Errorf("google: could not retrieve groups: %v", err)
 		}
+
+		if len(c.groups) > 0 {
+			groups = pkg_groups.Filter(groups, c.groups)
+			if len(groups) == 0 {
+				return identity, fmt.Errorf("google: user %q is not in any of the required groups", claims.Username)
+			}
+		}
 	}
 
 	identity = connector.Identity{
-- 
GitLab