From bda2fcbc29df817c442ad7a7a6f242518de9b6ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Taavi=20V=C3=A4=C3=A4n=C3=A4nen?= Date: Tue, 28 Sep 2021 15:10:54 +0300 Subject: [PATCH] refactor(auth): set groups during authentication MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of loading groups from config when they're checked, move group calculation to same place where the username itself is determined. This is needed to allow sourcing group membership from a HTTP header or similar in a future commit. Signed-off-by: Taavi Väänänen --- cmd/karma/acl.go | 4 +--- cmd/karma/auth.go | 13 ++++++++++++- cmd/karma/proxy.go | 4 ++-- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/cmd/karma/acl.go b/cmd/karma/acl.go index 3aaeb7cef..47531f2e4 100644 --- a/cmd/karma/acl.go +++ b/cmd/karma/acl.go @@ -112,9 +112,7 @@ type silenceACL struct { Matchers aclMatchers } -func (acl *silenceACL) isAllowed(amName string, silence *models.Silence, username string) (bool, error) { - groups := userGroups(username) - +func (acl *silenceACL) isAllowed(amName string, silence *models.Silence, groups []string) (bool, error) { groupMatch := len(acl.Scope.Groups) == 0 for _, aclGroup := range acl.Scope.Groups { if slices.StringInSlice(groups, aclGroup) { diff --git a/cmd/karma/auth.go b/cmd/karma/auth.go index 18190e6f8..ec075a29a 100644 --- a/cmd/karma/auth.go +++ b/cmd/karma/auth.go @@ -39,7 +39,9 @@ func headerAuth(name, valueRegex string, allowBypass []string) func(next http.Ha reg := regex.MustCompileAnchored(valueRegex) matches := reg.FindAllStringSubmatch(user, 1) if len(matches) > 0 && len(matches[0]) > 1 { - ctx := context.WithValue(r.Context(), authUserKey("user"), matches[0][1]) + userName := matches[0][1] + ctx := context.WithValue(r.Context(), authUserKey("user"), userName) + ctx = context.WithValue(ctx, authUserKey("groups"), userGroups(userName)) next.ServeHTTP(w, r.WithContext(ctx)) return } @@ -58,6 +60,14 @@ func getUserFromContext(r *http.Request) string { return username.(string) } +func getGroupsFromContext(r *http.Request) []string { + groups := r.Context().Value(authUserKey("groups")) + if groups == nil { + return []string{} + } + return groups.([]string) +} + func basicAuth(creds map[string]string, allowBypass []string) func(next http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -79,6 +89,7 @@ func basicAuth(creds map[string]string, allowBypass []string) func(next http.Han } ctx := context.WithValue(r.Context(), authUserKey("user"), user) + ctx = context.WithValue(ctx, authUserKey("groups"), userGroups(user)) next.ServeHTTP(w, r.WithContext(ctx)) }) } diff --git a/cmd/karma/proxy.go b/cmd/karma/proxy.go index 82d8ae98b..f76d79aa2 100644 --- a/cmd/karma/proxy.go +++ b/cmd/karma/proxy.go @@ -122,8 +122,8 @@ func handlePostRequest(alertmanager *alertmanager.Alertmanager, h http.Handler) } for i, acl := range silenceACLs { - username := getUserFromContext(r) - isAllowed, err := acl.isAllowed(alertmanager.Name, silence, username) + groups := getGroupsFromContext(r) + isAllowed, err := acl.isAllowed(alertmanager.Name, silence, groups) log.Debug().Int("index", i).Bool("allowed", isAllowed).Err(err).Msg("ACL rule check") if err != nil { log.Warn().Err(err).