From d8dfc5a12b772be55395e4dd2a5cce265a8e4e2d Mon Sep 17 00:00:00 2001 From: bjenuhb Date: Fri, 8 Sep 2023 09:09:37 +0530 Subject: [PATCH 01/11] feat: filter sso groups based on regex Signed-off-by: bjenuhb --- config/sso.go | 1 + server/auth/sso/sso.go | 65 ++++++++++++++++++++++++++---------------- 2 files changed, 42 insertions(+), 24 deletions(-) diff --git a/config/sso.go b/config/sso.go index 4c1a18254e2f..42591be0cbe3 100644 --- a/config/sso.go +++ b/config/sso.go @@ -21,6 +21,7 @@ type SSOConfig struct { CustomGroupClaimName string `json:"customGroupClaimName,omitempty"` UserInfoPath string `json:"userInfoPath,omitempty"` InsecureSkipVerify bool `json:"insecureSkipVerify,omitempty"` + FilterSSOGroupsRegex string `json:"filterSSOGroupsRegex,omitempty"` } func (c SSOConfig) GetSessionExpiry() time.Duration { diff --git a/server/auth/sso/sso.go b/server/auth/sso/sso.go index bd9603e55637..c85cf0ddd07c 100644 --- a/server/auth/sso/sso.go +++ b/server/auth/sso/sso.go @@ -9,6 +9,7 @@ import ( "crypto/x509" "fmt" "net/http" + "regexp" "strings" "time" @@ -49,18 +50,19 @@ var _ Interface = &sso{} type Config = config.SSOConfig type sso struct { - config *oauth2.Config - issuer string - idTokenVerifier *oidc.IDTokenVerifier - httpClient *http.Client - baseHRef string - secure bool - privateKey crypto.PrivateKey - encrypter jose.Encrypter - rbacConfig *config.RBACConfig - expiry time.Duration - customClaimName string - userInfoPath string + config *oauth2.Config + issuer string + idTokenVerifier *oidc.IDTokenVerifier + httpClient *http.Client + baseHRef string + secure bool + privateKey crypto.PrivateKey + encrypter jose.Encrypter + rbacConfig *config.RBACConfig + expiry time.Duration + customClaimName string + userInfoPath string + filterSsoGroupsRegex string } func (s *sso) IsRBACEnabled() bool { @@ -188,18 +190,19 @@ func newSso( log.WithFields(lf).Info("SSO configuration") return &sso{ - config: config, - idTokenVerifier: idTokenVerifier, - baseHRef: baseHRef, - httpClient: httpClient, - secure: secure, - privateKey: privateKey, - encrypter: encrypter, - rbacConfig: c.RBAC, - expiry: c.GetSessionExpiry(), - customClaimName: c.CustomGroupClaimName, - userInfoPath: c.UserInfoPath, - issuer: c.Issuer, + config: config, + idTokenVerifier: idTokenVerifier, + baseHRef: baseHRef, + httpClient: httpClient, + secure: secure, + privateKey: privateKey, + encrypter: encrypter, + rbacConfig: c.RBAC, + expiry: c.GetSessionExpiry(), + customClaimName: c.CustomGroupClaimName, + userInfoPath: c.UserInfoPath, + issuer: c.Issuer, + filterSsoGroupsRegex: c.FilterSSOGroupsRegex, }, nil } @@ -280,6 +283,20 @@ func (s *sso) HandleCallback(w http.ResponseWriter, r *http.Request) { return } } + if s.filterSsoGroupsRegex != "" { + var filteredGroups []string + regex, err := regexp.Compile(s.filterSsoGroupsRegex) + if err != nil { + log.WithError(err).Errorf("failed to compile filterSsoGroupsRegex: %s", s.filterSsoGroupsRegex) + } else { + for _, group := range groups { + if regex.Match([]byte(group)) { + filteredGroups = append(filteredGroups, group) + } + } + groups = filteredGroups + } + } argoClaims := &types.Claims{ Claims: jwt.Claims{ Issuer: issuer, From 44b84a30daf729c97b1fd7b6313f8f1613ec95b6 Mon Sep 17 00:00:00 2001 From: bjenuhb Date: Fri, 8 Sep 2023 11:23:35 +0530 Subject: [PATCH 02/11] ci: empty commit for build Signed-off-by: bjenuhb From 38c2b770f0ff653fb30d840ce5b5c8596f40f7f8 Mon Sep 17 00:00:00 2001 From: bjenuhb Date: Fri, 8 Sep 2023 12:17:01 +0530 Subject: [PATCH 03/11] feat: pre initialize regex Signed-off-by: bjenuhb --- config/sso.go | 2 +- server/auth/sso/sso.go | 74 ++++++++++++++++++++++-------------------- 2 files changed, 39 insertions(+), 37 deletions(-) diff --git a/config/sso.go b/config/sso.go index 42591be0cbe3..5233f4c5aa8a 100644 --- a/config/sso.go +++ b/config/sso.go @@ -21,7 +21,7 @@ type SSOConfig struct { CustomGroupClaimName string `json:"customGroupClaimName,omitempty"` UserInfoPath string `json:"userInfoPath,omitempty"` InsecureSkipVerify bool `json:"insecureSkipVerify,omitempty"` - FilterSSOGroupsRegex string `json:"filterSSOGroupsRegex,omitempty"` + FilterGroupsRegex string `json:"filterGroupsRegex,omitempty"` } func (c SSOConfig) GetSessionExpiry() time.Duration { diff --git a/server/auth/sso/sso.go b/server/auth/sso/sso.go index c85cf0ddd07c..007e11ae24bd 100644 --- a/server/auth/sso/sso.go +++ b/server/auth/sso/sso.go @@ -50,19 +50,19 @@ var _ Interface = &sso{} type Config = config.SSOConfig type sso struct { - config *oauth2.Config - issuer string - idTokenVerifier *oidc.IDTokenVerifier - httpClient *http.Client - baseHRef string - secure bool - privateKey crypto.PrivateKey - encrypter jose.Encrypter - rbacConfig *config.RBACConfig - expiry time.Duration - customClaimName string - userInfoPath string - filterSsoGroupsRegex string + config *oauth2.Config + issuer string + idTokenVerifier *oidc.IDTokenVerifier + httpClient *http.Client + baseHRef string + secure bool + privateKey crypto.PrivateKey + encrypter jose.Encrypter + rbacConfig *config.RBACConfig + expiry time.Duration + customClaimName string + userInfoPath string + filterGroupsRegex *regexp.Regexp } func (s *sso) IsRBACEnabled() bool { @@ -187,22 +187,29 @@ func newSso( if c.IssuerAlias != "" { lf["issuerAlias"] = c.IssuerAlias } + var filterGroupRegex *regexp.Regexp = nil + if c.FilterGroupsRegex != "" { + filterGroupRegex, err = regexp.Compile(c.FilterGroupsRegex) + if err != nil { + return nil, fmt.Errorf("failed to compile sso.filterGroupRegex: %s %w", c.FilterGroupsRegex, err) + } + } log.WithFields(lf).Info("SSO configuration") return &sso{ - config: config, - idTokenVerifier: idTokenVerifier, - baseHRef: baseHRef, - httpClient: httpClient, - secure: secure, - privateKey: privateKey, - encrypter: encrypter, - rbacConfig: c.RBAC, - expiry: c.GetSessionExpiry(), - customClaimName: c.CustomGroupClaimName, - userInfoPath: c.UserInfoPath, - issuer: c.Issuer, - filterSsoGroupsRegex: c.FilterSSOGroupsRegex, + config: config, + idTokenVerifier: idTokenVerifier, + baseHRef: baseHRef, + httpClient: httpClient, + secure: secure, + privateKey: privateKey, + encrypter: encrypter, + rbacConfig: c.RBAC, + expiry: c.GetSessionExpiry(), + customClaimName: c.CustomGroupClaimName, + userInfoPath: c.UserInfoPath, + issuer: c.Issuer, + filterGroupsRegex: filterGroupRegex, }, nil } @@ -283,19 +290,14 @@ func (s *sso) HandleCallback(w http.ResponseWriter, r *http.Request) { return } } - if s.filterSsoGroupsRegex != "" { + if s.filterGroupsRegex != nil { var filteredGroups []string - regex, err := regexp.Compile(s.filterSsoGroupsRegex) - if err != nil { - log.WithError(err).Errorf("failed to compile filterSsoGroupsRegex: %s", s.filterSsoGroupsRegex) - } else { - for _, group := range groups { - if regex.Match([]byte(group)) { - filteredGroups = append(filteredGroups, group) - } + for _, group := range groups { + if s.filterGroupsRegex.Match([]byte(group)) { + filteredGroups = append(filteredGroups, group) } - groups = filteredGroups } + groups = filteredGroups } argoClaims := &types.Claims{ Claims: jwt.Claims{ From e15387a0b9bd9822f9599481d0d243b8c46fe869 Mon Sep 17 00:00:00 2001 From: bjenuhb Date: Fri, 8 Sep 2023 13:13:52 +0530 Subject: [PATCH 04/11] ci: empty commit for build Signed-off-by: bjenuhb From 1dfd1eb77da054895ca253d06b098c99b07933d7 Mon Sep 17 00:00:00 2001 From: bjenuhb Date: Fri, 8 Sep 2023 21:51:31 +0530 Subject: [PATCH 05/11] feat: make filterGroupRegex a list Signed-off-by: bjenuhb --- config/sso.go | 8 ++++---- server/auth/sso/sso.go | 24 +++++++++++++++--------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/config/sso.go b/config/sso.go index 5233f4c5aa8a..6e288d2d3cf2 100644 --- a/config/sso.go +++ b/config/sso.go @@ -18,10 +18,10 @@ type SSOConfig struct { Scopes []string `json:"scopes,omitempty"` SessionExpiry metav1.Duration `json:"sessionExpiry,omitempty"` // customGroupClaimName will override the groups claim name - CustomGroupClaimName string `json:"customGroupClaimName,omitempty"` - UserInfoPath string `json:"userInfoPath,omitempty"` - InsecureSkipVerify bool `json:"insecureSkipVerify,omitempty"` - FilterGroupsRegex string `json:"filterGroupsRegex,omitempty"` + CustomGroupClaimName string `json:"customGroupClaimName,omitempty"` + UserInfoPath string `json:"userInfoPath,omitempty"` + InsecureSkipVerify bool `json:"insecureSkipVerify,omitempty"` + FilterGroupsRegex []string `json:"filterGroupsRegex,omitempty"` } func (c SSOConfig) GetSessionExpiry() time.Duration { diff --git a/server/auth/sso/sso.go b/server/auth/sso/sso.go index 007e11ae24bd..a4053eb86d9d 100644 --- a/server/auth/sso/sso.go +++ b/server/auth/sso/sso.go @@ -62,7 +62,7 @@ type sso struct { expiry time.Duration customClaimName string userInfoPath string - filterGroupsRegex *regexp.Regexp + filterGroupsRegex []*regexp.Regexp } func (s *sso) IsRBACEnabled() bool { @@ -187,11 +187,14 @@ func newSso( if c.IssuerAlias != "" { lf["issuerAlias"] = c.IssuerAlias } - var filterGroupRegex *regexp.Regexp = nil - if c.FilterGroupsRegex != "" { - filterGroupRegex, err = regexp.Compile(c.FilterGroupsRegex) - if err != nil { - return nil, fmt.Errorf("failed to compile sso.filterGroupRegex: %s %w", c.FilterGroupsRegex, err) + var filterGroupRegex []*regexp.Regexp + if c.FilterGroupsRegex != nil && len(c.FilterGroupsRegex) > 0 { + for _, regex := range c.FilterGroupsRegex { + compiledRegex, err := regexp.Compile(regex) + if err != nil { + return nil, fmt.Errorf("failed to compile sso.filterGroupRegex: %s %w", regex, err) + } + filterGroupRegex = append(filterGroupRegex, compiledRegex) } } log.WithFields(lf).Info("SSO configuration") @@ -290,11 +293,14 @@ func (s *sso) HandleCallback(w http.ResponseWriter, r *http.Request) { return } } - if s.filterGroupsRegex != nil { + if s.filterGroupsRegex != nil && len(s.filterGroupsRegex) > 0 { var filteredGroups []string for _, group := range groups { - if s.filterGroupsRegex.Match([]byte(group)) { - filteredGroups = append(filteredGroups, group) + for _, regex := range s.filterGroupsRegex { + if regex.MatchString(group) { + filteredGroups = append(filteredGroups, group) + break + } } } groups = filteredGroups From b1ea29b6530231cf791f204f2235dfbecf8586f1 Mon Sep 17 00:00:00 2001 From: bjenuhb Date: Fri, 8 Sep 2023 21:53:27 +0530 Subject: [PATCH 06/11] feat: make filterGroupRegex a list Signed-off-by: bjenuhb --- server/auth/sso/sso.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/auth/sso/sso.go b/server/auth/sso/sso.go index a4053eb86d9d..946e63d2ca8f 100644 --- a/server/auth/sso/sso.go +++ b/server/auth/sso/sso.go @@ -187,14 +187,14 @@ func newSso( if c.IssuerAlias != "" { lf["issuerAlias"] = c.IssuerAlias } - var filterGroupRegex []*regexp.Regexp + var filterGroupsRegex []*regexp.Regexp if c.FilterGroupsRegex != nil && len(c.FilterGroupsRegex) > 0 { for _, regex := range c.FilterGroupsRegex { compiledRegex, err := regexp.Compile(regex) if err != nil { return nil, fmt.Errorf("failed to compile sso.filterGroupRegex: %s %w", regex, err) } - filterGroupRegex = append(filterGroupRegex, compiledRegex) + filterGroupsRegex = append(filterGroupsRegex, compiledRegex) } } log.WithFields(lf).Info("SSO configuration") @@ -212,7 +212,7 @@ func newSso( customClaimName: c.CustomGroupClaimName, userInfoPath: c.UserInfoPath, issuer: c.Issuer, - filterGroupsRegex: filterGroupRegex, + filterGroupsRegex: filterGroupsRegex, }, nil } From e46961456083f237dba3fd764c2c77398ba20e45 Mon Sep 17 00:00:00 2001 From: bjenuhb Date: Sat, 9 Sep 2023 07:03:05 +0530 Subject: [PATCH 07/11] ci: empty commit for build Signed-off-by: bjenuhb From 157b1371c50f61a73ab057a025300fffe843b2a4 Mon Sep 17 00:00:00 2001 From: bjenuhb Date: Sat, 9 Sep 2023 07:45:03 +0530 Subject: [PATCH 08/11] ci: empty commit for build Signed-off-by: bjenuhb From 4194ac8443d593d6a29aeab39edfff779418aa57 Mon Sep 17 00:00:00 2001 From: bjenuhb Date: Sun, 10 Sep 2023 03:29:26 +0530 Subject: [PATCH 09/11] fix: stylistic issues Signed-off-by: bjenuhb --- server/auth/sso/sso.go | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/server/auth/sso/sso.go b/server/auth/sso/sso.go index 946e63d2ca8f..a6179214acc8 100644 --- a/server/auth/sso/sso.go +++ b/server/auth/sso/sso.go @@ -183,10 +183,7 @@ func newSso( if err != nil { return nil, fmt.Errorf("failed to create JWT encrpytor: %w", err) } - lf := log.Fields{"redirectUrl": config.RedirectURL, "issuer": c.Issuer, "issuerAlias": "DISABLED", "clientId": c.ClientID, "scopes": config.Scopes, "insecureSkipVerify": c.InsecureSkipVerify} - if c.IssuerAlias != "" { - lf["issuerAlias"] = c.IssuerAlias - } + var filterGroupsRegex []*regexp.Regexp if c.FilterGroupsRegex != nil && len(c.FilterGroupsRegex) > 0 { for _, regex := range c.FilterGroupsRegex { @@ -197,6 +194,11 @@ func newSso( filterGroupsRegex = append(filterGroupsRegex, compiledRegex) } } + + lf := log.Fields{"redirectUrl": config.RedirectURL, "issuer": c.Issuer, "issuerAlias": "DISABLED", "clientId": c.ClientID, "scopes": config.Scopes, "insecureSkipVerify": c.InsecureSkipVerify, "filterGroupsRegex": c.FilterGroupsRegex} + if c.IssuerAlias != "" { + lf["issuerAlias"] = c.IssuerAlias + } log.WithFields(lf).Info("SSO configuration") return &sso{ @@ -293,6 +295,8 @@ func (s *sso) HandleCallback(w http.ResponseWriter, r *http.Request) { return } } + + // only return groups that match at least one of the regexes if s.filterGroupsRegex != nil && len(s.filterGroupsRegex) > 0 { var filteredGroups []string for _, group := range groups { @@ -305,6 +309,7 @@ func (s *sso) HandleCallback(w http.ResponseWriter, r *http.Request) { } groups = filteredGroups } + argoClaims := &types.Claims{ Claims: jwt.Claims{ Issuer: issuer, From 6b6742b9fa3dd8e880f5ccc9df26a9d38bf96825 Mon Sep 17 00:00:00 2001 From: bjenuhb Date: Sun, 10 Sep 2023 03:31:50 +0530 Subject: [PATCH 10/11] fix: stylistic issues Signed-off-by: bjenuhb --- server/auth/sso/sso.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/server/auth/sso/sso.go b/server/auth/sso/sso.go index a6179214acc8..b0ea0819a9f0 100644 --- a/server/auth/sso/sso.go +++ b/server/auth/sso/sso.go @@ -195,10 +195,13 @@ func newSso( } } - lf := log.Fields{"redirectUrl": config.RedirectURL, "issuer": c.Issuer, "issuerAlias": "DISABLED", "clientId": c.ClientID, "scopes": config.Scopes, "insecureSkipVerify": c.InsecureSkipVerify, "filterGroupsRegex": c.FilterGroupsRegex} + lf := log.Fields{"redirectUrl": config.RedirectURL, "issuer": c.Issuer, "issuerAlias": "DISABLED", "clientId": c.ClientID, "scopes": config.Scopes, "insecureSkipVerify": c.InsecureSkipVerify} if c.IssuerAlias != "" { lf["issuerAlias"] = c.IssuerAlias } + if c.FilterGroupsRegex != nil && len(c.FilterGroupsRegex) > 0 { + lf["filterGroupsRegex"] = c.FilterGroupsRegex + } log.WithFields(lf).Info("SSO configuration") return &sso{ @@ -309,7 +312,7 @@ func (s *sso) HandleCallback(w http.ResponseWriter, r *http.Request) { } groups = filteredGroups } - + argoClaims := &types.Claims{ Claims: jwt.Claims{ Issuer: issuer, From 3358f577437bb34ab31eb390ec66cfa304826f5a Mon Sep 17 00:00:00 2001 From: bjenuhb Date: Sun, 10 Sep 2023 09:25:41 +0530 Subject: [PATCH 11/11] feat: log filterGroupsRegex Signed-off-by: bjenuhb --- server/auth/sso/sso.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/server/auth/sso/sso.go b/server/auth/sso/sso.go index b0ea0819a9f0..2d238bba0ab5 100644 --- a/server/auth/sso/sso.go +++ b/server/auth/sso/sso.go @@ -195,13 +195,10 @@ func newSso( } } - lf := log.Fields{"redirectUrl": config.RedirectURL, "issuer": c.Issuer, "issuerAlias": "DISABLED", "clientId": c.ClientID, "scopes": config.Scopes, "insecureSkipVerify": c.InsecureSkipVerify} + lf := log.Fields{"redirectUrl": config.RedirectURL, "issuer": c.Issuer, "issuerAlias": "DISABLED", "clientId": c.ClientID, "scopes": config.Scopes, "insecureSkipVerify": c.InsecureSkipVerify, "filterGroupsRegex": c.FilterGroupsRegex} if c.IssuerAlias != "" { lf["issuerAlias"] = c.IssuerAlias } - if c.FilterGroupsRegex != nil && len(c.FilterGroupsRegex) > 0 { - lf["filterGroupsRegex"] = c.FilterGroupsRegex - } log.WithFields(lf).Info("SSO configuration") return &sso{