From 4c1b667f63dbe02831f03dcff22895cd0583f664 Mon Sep 17 00:00:00 2001 From: Matej Vrzala Date: Wed, 11 Nov 2026 18:25:22 +0100 Subject: [PATCH] fix(service): evaluate user allow list when block list does not match When Users.Block was configured, UserAllowedRule returned EffectAllow immediately whenever the user was not present in the block list. This completely bypassed the Users.Allow list when both block and allow lists were defined, granting access to any unblocked user regardless of allow list restrictions. Now, if a user is not in the block list, evaluation proceeds to check Users.Allow. If an allow list is configured, only users matching it are allowed; if no allow list is configured, unblocked users continue to be allowed. Reported-by: BS.ehlas.cz --- internal/service/access_controls_rules.go | 4 +- .../service/access_controls_rules_test.go | 60 +++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/internal/service/access_controls_rules.go b/internal/service/access_controls_rules.go index 318894d2..b8c805a8 100644 --- a/internal/service/access_controls_rules.go +++ b/internal/service/access_controls_rules.go @@ -69,7 +69,6 @@ func (rule *UserAllowedRule) Evaluate(ctx *ACLContext) Effect { rule.Log.App.Debug().Str("username", ctx.UserContext.GetUsername()).Msg("User is in users block list, denying access") return EffectDeny } - return EffectAllow } rule.Log.App.Debug().Msg("Checking users allow list") @@ -78,6 +77,9 @@ func (rule *UserAllowedRule) Evaluate(ctx *ACLContext) Effect { if err != nil { if errors.Is(err, utils.ErrFilterEmpty) { + if ctx.ACLs.Users.Block != "" { + return EffectAllow + } return EffectAbstain } rule.Log.App.Warn().Err(err).Str("item", ctx.UserContext.GetUsername()).Msg("Invalid entry in users allow list") diff --git a/internal/service/access_controls_rules_test.go b/internal/service/access_controls_rules_test.go index 7cb0f8ba..3394f0bd 100644 --- a/internal/service/access_controls_rules_test.go +++ b/internal/service/access_controls_rules_test.go @@ -212,6 +212,66 @@ func TestUserAllowedRule(t *testing.T) { }, expected: EffectDeny, }, + { + name: "denies user when both block and allow configured and user in block list", + ctx: &ACLContext{ + ACLs: &model.App{ + Users: model.AppUsers{Block: "evil", Allow: "alice,bob"}, + }, + UserContext: &model.UserContext{ + Provider: model.ProviderLocal, + Local: &model.LocalContext{ + BaseContext: model.BaseContext{Username: "evil"}, + }, + }, + }, + expected: EffectDeny, + }, + { + name: "allows user when both block and allow configured and user in allow list", + ctx: &ACLContext{ + ACLs: &model.App{ + Users: model.AppUsers{Block: "evil", Allow: "alice,bob"}, + }, + UserContext: &model.UserContext{ + Provider: model.ProviderLocal, + Local: &model.LocalContext{ + BaseContext: model.BaseContext{Username: "alice"}, + }, + }, + }, + expected: EffectAllow, + }, + { + name: "denies user when both block and allow configured and user in neither", + ctx: &ACLContext{ + ACLs: &model.App{ + Users: model.AppUsers{Block: "evil", Allow: "alice,bob"}, + }, + UserContext: &model.UserContext{ + Provider: model.ProviderLocal, + Local: &model.LocalContext{ + BaseContext: model.BaseContext{Username: "charlie"}, + }, + }, + }, + expected: EffectDeny, + }, + { + name: "denies user when both block and allow match same user", + ctx: &ACLContext{ + ACLs: &model.App{ + Users: model.AppUsers{Block: "alice", Allow: "alice,bob"}, + }, + UserContext: &model.UserContext{ + Provider: model.ProviderLocal, + Local: &model.LocalContext{ + BaseContext: model.BaseContext{Username: "alice"}, + }, + }, + }, + expected: EffectDeny, + }, } for _, tt := range tests {