authelia/internal/handlers/handler_authz_util.go

106 lines
3.1 KiB
Go

package handlers
import (
"github.com/authelia/authelia/v4/internal/authentication"
"github.com/authelia/authelia/v4/internal/authorization"
"github.com/authelia/authelia/v4/internal/middlewares"
"github.com/authelia/authelia/v4/internal/session"
"github.com/authelia/authelia/v4/internal/utils"
)
func friendlyMethod(m string) (fm string) {
switch m {
case "":
return "unknown"
default:
return m
}
}
func friendlyUsername(username string) (fusername string) {
switch username {
case "":
return anonymous
default:
return username
}
}
func isAuthzResult(level authentication.Level, required authorization.Level, ruleHasSubject bool) AuthzResult {
switch {
case required == authorization.Bypass:
return AuthzResultAuthorized
case required == authorization.Denied && (level != authentication.NotAuthenticated || !ruleHasSubject):
// If the user is not anonymous, it means that we went through all the rules related to that user identity and
// can safely conclude their access is actually forbidden. If a user is anonymous however this is not actually
// possible without some more advanced logic.
return AuthzResultForbidden
case required == authorization.OneFactor && level >= authentication.OneFactor,
required == authorization.TwoFactor && level >= authentication.TwoFactor:
return AuthzResultAuthorized
default:
return AuthzResultUnauthorized
}
}
// generateVerifySessionHasUpToDateProfileTraceLogs is used to generate trace logs only when trace logging is enabled.
// The information calculated in this function is completely useless other than trace for now.
func generateVerifySessionHasUpToDateProfileTraceLogs(ctx *middlewares.AutheliaCtx, userSession *session.UserSession,
details *authentication.UserDetails) {
groupsAdded, groupsRemoved := utils.StringSlicesDelta(userSession.Groups, details.Groups)
emailsAdded, emailsRemoved := utils.StringSlicesDelta(userSession.Emails, details.Emails)
nameDelta := userSession.DisplayName != details.DisplayName
fields := map[string]any{"username": userSession.Username}
msg := "User session groups are current"
if len(groupsAdded) != 0 || len(groupsRemoved) != 0 {
if len(groupsAdded) != 0 {
fields["added"] = groupsAdded
}
if len(groupsRemoved) != 0 {
fields["removed"] = groupsRemoved
}
msg = "User session groups were updated"
}
ctx.Logger.WithFields(fields).Trace(msg)
if len(emailsAdded) != 0 || len(emailsRemoved) != 0 {
if len(emailsAdded) != 0 {
fields["added"] = emailsAdded
} else {
delete(fields, "added")
}
if len(emailsRemoved) != 0 {
fields["removed"] = emailsRemoved
} else {
delete(fields, "removed")
}
msg = "User session emails were updated"
} else {
msg = "User session emails are current"
delete(fields, "added")
delete(fields, "removed")
}
ctx.Logger.WithFields(fields).Trace(msg)
if nameDelta {
ctx.Logger.
WithFields(map[string]any{
"username": userSession.Username,
"before": userSession.DisplayName,
"after": details.DisplayName,
}).
Trace("User session display name updated")
} else {
ctx.Logger.Trace("User session display name is current")
}
}