refactor(auth): set groups during authentication

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 <hi@taavi.wtf>
This commit is contained in:
Taavi Väänänen
2021-09-28 15:10:54 +03:00
committed by Łukasz Mierzwa
parent 4893b171da
commit bda2fcbc29
3 changed files with 15 additions and 6 deletions

View File

@@ -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) {

View File

@@ -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))
})
}

View File

@@ -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).